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/