[Rumble-jp-dev] Re: ソースの文字

Back to archive index

Naoki Kurosawa naoki_kuros****@ybb*****
2004年 3月 25日 (木) 01:50:34 JST


黒澤です。

> RobotDetailFormのrobot_detailは、バージョンごとに
> mySQLのrobot_versionのメンバがごっそり入っていて
> 最新が先頭のリストですが、
> その先頭のリストのみにアクセスしたい場合、
> 
> javaでいうところの
> target_robot = (型)RobotDetailForm.robot_detail.first();
>> <bean:define id="target_robot" name="RobotDetailForm" 
> type=...  .../>
> の...あたりは何を記述してあげればいいのでしょうか?

これなら、

<bean:define id="target_robot" name="RobotDetailForm"
    property="robot_detail[0]"
    type="org.apache.commons.beanutils.DynaBean"/>
としてください。
で、
<bean:write name="target_robot" property="class_name"/>
てな感じでさらにその中身にアクセスできます。


直接的に、
<bean:write name="RobotDetailForm"
    property="robot_detail[0].class_name"/>
でもいいです。


ただこれ、BLの中で
SELECT * FROM robot_version rv WHERE rv.robot_version_id = ?
とやっていて、この結果は1行しかないことがわかっているわけですから、
BL内でList.get(0)してやったほうがいいですよ。

#正確に言えば、存在しないrobot_version_idが指定されたときは
#結果が0行なので、0行でないことを確認しないといけませんが。

■Form定義
<form-bean name="RobotDetailForm"
    type="org.apache.struts.action.DynaActionForm">
    <form-property name="retMessage" type="java.lang.String"/>
    <form-property name="robot_version_id" type="java.lang.String"/>
    <form-property name="robot_detail" type="java.util.List"/>
</form-bean>

を、

<form-bean name="RobotDetailForm"
    type="org.apache.struts.action.DynaActionForm">
    <form-property name="retMessage" type="java.lang.String"/>
    <form-property name="robot_version_id" type="java.lang.String"/>
    <form-property name="robot_detail"
        type="org.apache.commons.beanutils.DynaBean"/> ←修正
</form-bean>

■現状のBLコード
    ResultSet rs = stmt.executeQuery();
    RowSetDynaClass dc = new RowSetDynaClass(rs);
    stmt.close();
    form.set("robot_detail", dc.getRows());
    // dc.getRows()はListを返す

を
    ResultSet rs = stmt.executeQuery();
    RowSetDynaClass dc = new RowSetDynaClass(rs);
    stmt.close();
    form.set("robot_detail", dc.getRows().get(0)); ←修正


するとJSPではもうちょっと直接的に
<bean:write name="RobotDetailForm"
    property="robot_detail.class_name"/>
と書けます。


ちなみに、
jakarta commons-beanutilsは、Strutsから分離したプロジェクトです。
■機能その1 - JavaBeanのgetter/setterアクセス
○任意のJavaBeanのgetter/setterに"."(ピリオド)記法でアクセスする。

public class Hoge {
}
public class Moge {
    private Hoge hoge;
    public Hoge getHoge();
    public void setMoge();
}
というクラスがあったとき、
Mogeのインスタンスmogeに対してmoge.hogeとアクセスすることで、
mogeのgetMoge()を呼ぶのと同じ効果をもたらします。
"."で繋げることで、
moge.hoge.koge    (イコール moge.getHoge().getKoge())
とかいう感じでアクセスしていけます。
Strutsのタグライブラリはこれを使ってActionFormへのアクセスを行います。

○Mapオブジェクトに"."記法でアクセスする
Mapオブジェクトmogeにmoge.hogeとかアクセスすると、
mogeのget("hoge")を呼ぶのと同じ効果をもたらします。
moge['hoge']なんていう書き方もできます。

○Listオブジェクトに[n]記法でアクセスする
Listオブジェクトmogeにmoge[0]とかアクセスすると、
mogeのget(0)を呼ぶのと同じ効果をもたらします。

■機能その2 - Javaクラスを書かずに、定義ベースでJavaBeanを生成する

ActionFormをstruts-config.xml内で定義している機能です。
生成されるJavaBeanはorg.apache.commons.beanutils.DynaBeanという
インターフェースを実装しています。
ActionFormもimplements DynaBeanです。

要はDynaBeanというのは汎用のJavaBeanです。
Object get(String name);
void set(String name, Object value);
というメソッドを持ちます。
定義によってname引数に渡せる変数名とデータ型を決めるという感じです。

で、機能その1をつかって"."記法アクセスできます。

<bean:write name="target_robot" property="class_name"/>
とか
<bean:write name="RobotDetailForm"
    property="robot_detail[0].class_name"/>
とかいうのはその例です。


■機能その3 - SQLクエリのResultSetからDynaBeanを生成する
ResultSetのメタデータ(カラム名やデータ型)からDynaBeanを生成する。
ResultSetの1行分をDynaBeanの1インスタンスとする。
ResultSetからは複数行のデータが返るので、DynaBeanのListが手に入る。



Jakarta commons-beanutilsの対抗馬として、
DynClassというプロジェクトもあります。
http://dynclass.sourceforge.net
こちらもJavaクラスを書かずに動的にJavaBeanを生成するんですが、
汎用のget(String), set(String, Object)メソッドを持つのではなく、
getHoge()とかsetHoge()とか、本物のメソッドを作る仕組みです。
動的にクラスを作るようなものです。
こちらの方が汎用性が高いです。
なんですが、Strutsの中では簡単には使えません。

以上長い蛇足でした。

-- 
Naoki Kurosawa <naoki_kuros****@ybb*****>
Sharpen up JAVA skills. - Robocode Rumble-JP Project -
http://rumble-jp.sourceforge.jp/    http://robocode.ddo.jp/rumblejp/




Rumble-jp-dev メーリングリストの案内
Back to archive index