Friday, September 30, 2005

JSF+Hibernate

仕事の関係で今ちょこちょこと調査を進めてるJSFとHibernate。
しかしHibernateってば、トランザクションまわりの処理とか
DBアクセス関連処理を一手に引き受けてくれるから非常に便利。
と思っていたが、やっぱしSQLを一切書かないプロジェクトなんて
存在するはずない。そんなわけで、ネイティブなSQLをHibernate
経由で発行したいって思うのは結構普通なニーズだと思われる。
けどこれがまたかなり厄介だった。HibernateにはHQLなんて
専用のSQL文があるけど、この方言が結構曲者で、覚えるのは
ずいぶん骨が折れる。createSQLQuery関数で独自のSQLが
流せるけど、これも完全に自由なSQLが書けるということでも
なさそう。
そんで今回一番詰まったのが、複数テーブルを使うSELECT文で、
取得した結果セットをJSFのdataTableタグで表示する方法。
そこらのサイトで複数テーブルをJoinするSQLクエリの書き方
というのはぼちぼち目にしたけど、その結果をJSFで表示する
事例がなかった!この方法がわかるまでにずいぶんと時間が
かかってしまった・・・。忘れないようにメモっておくと、
Hibernateのlist関数の戻り値はListオブジェクトだが、
その中で各テーブルの情報はオブジェクト配列で保持されて
いるということがわかった。み、みんなハマらないのだろうか?
俺だけ・・・?

例えば、以下のようなSQLの場合、

SELECT {user.*}, {group.*}
FROM t_user {user} INNER JOIN t_group {group}
 ON {user}.user_no = {group}.user_no;

結果の取り出しは以下のようになるようだ。

List result = query.list(
         strSql,
         new String[] {"user", "group"},
         new Class[] {User.class, Group.class});

Object[] obj = result.get(0);
User user = (User)obj[0];
Group group = (Group)obj[1];

とこんな感じ。最初のテーブルがオブジェクト配列の0番目に、
次のテーブルは配列の1番目に格納されるという仕組みらしい。
んで、これをJSFのdataTableで表示しようとすると以下のように
なってくる。

// Java
itemtable = new UIData();
itemtable.setValue(result);

// Jsp
<h:dataTable id="table" border="1"
 binding="#{managedBean.itemtable}"
 value="#{managedBean.result}" var="userdata">

 <h:outputText value="#{userdata[0].user_no}" />
 <h:outputText value="#{userdata[1].group_name}" />
</h:dataTable>

んー、実際にできてしまえばシンプルで何のことはないが、
知らないとホントに難しい。まーでも、何とか思い通りの
クエリを発行して画面で表示できるようになった。

しかし、SELECTするカラムを指定するとエラーになったり
まだまだ調査せにゃならんタスクは山ほど・・・。実装開始
までもう時間が無いし、早いとこプロトタイプを煮詰めないと
いけないな~。頑張ろ。

No comments: