S2 Hibernate Plugin
S2自身をコンパクトに保ちながら、機能追加をしていくために
Plugin形態を取ろうと思ってます。
PluginはS2自身から配布も切り離されます。
その第一弾は、S2 Hibernate Plugin。
意外に思う方も多いかもしれません。
S2Daoをやらないというわけではなく、
O/Rマッピングツールの中で、最も評価が高く
ユーザも多いであろうHibernateをS2でサポートすることは
ニーズが高いと思ったためです。
使い方はこんな感じ。
EmployeeDao.java
EmployeeDaoImpl.java
interface EmployeeDao {
public Employee getEmployee(String name);
}
AbstractHibernateDao.getSession()で提供されるセッションは、
class EmployeeDaoImpl extends AbstractHibernateDao
implements EmployeeDao {EmployeeDaoImpl(SessionFactory factory) {
super(factory);
}
public Employee getEmployee(String name) {
return getSession().find(
"from Employee where name = ?"
name, Hibernate.STRING);
}
}
openもcloseも必要ありません。S2のJTAに連動します。
そのため、同一DAOのメソッド間でも同一トランザクションで
あれば、セッションは維持されますし、異なるDAO、異なるサービス間でも
同一トランザクションであれば、セッションは維持されます。
SQLを意識したくない場合は、Hibernate、SQLを自前で
コントロールしたい場合は、DbUtils,S2Daoのような
使い分けになるのかなぁと思います。
SQLのツールとの連動
ひがさんのところで、Seasar2のデータ層のソリューションにHibernateをまずリリースしようか考えていることを書かれてます。私はSQLをごりごりごりごり書きたいごりごり。
未来に使ってくれる人より、今使ってくれる人を大事にしたいため、
S2Daoを先にリリースします。(^^;
SQL文の外部化ですが、バインド変数や動的SQL文の生成などを考えると
生のSQL文をそのままXMLには記述できないと思います。
なんかツール(antなど)を作ってXMLから生のSQLをはかせ、
そいつをSQL*Plusなどで実行する手もありますが、
ちょっとめんどくさい。
TapestryのSQL版として、SQL*Plusなどで直接実行できるが
実行時には動的に値が変わるなんてことができるとうれしい。
そこで考えてみました。
のようにSQL文を記述します。SQL*Plusではそのまま実行できます。
SELECT empno, ename FROM emp
--S2 7788 -> ?{empno}
WHERE empno = 7788
S2Daoが実行するときには、--S2コメント分を見つけると次の行の
該当する文字列をバインド変数に置き換えて、引数のempnoを
バインドして実行します。
S2Daoは次のように解釈します。
SQLツールでそのまま実行できるというのがコンセプトで、
SELECT empno, ename FROM emp
WHERE empno = ?{empno}
SQLデザイナ(?)と開発者のスムースな分業が可能になります。
ハイブリッドSQL
なるほど。SQLコメントでSQLデザイナーとプログラマーで分業をやるという。悪乗りしてTapestry的ならこっちか?
SELECT empno, ename FROM emp
WHERE empno = /*S2*/7788/*?{empno}*/とか?トークン内部の一部置き換えはできなくなっちゃいますけど。
ちょっとみにくいけど、置き換えできる範囲を自由に指定できるようになりますね。
動的に変わるSQL文をJavaで自由に組み立てられるようになります。
SELECT empno, ename FROM emp
/*S2*/WHERE job = 'CLERK' AND deptno = 10/*this.hoge()*/
class MyDaoImpl extends S2Dao {
//S2コメントの部分を置き換える
public void hoge(QueryContext ctx) {
//ctx.addSql(String)でSQL文の追加
//ctx.addSql(String sql, Object var)SQLを追加しながら
//バインド変数の追加
//ctx.getArg(String name)で引数の取得
自由にSQL文を組み立てる
ctx.addSql(" WHERE job = ?", ctx.getArg("job"));
ctx.addSql(" AND deptno = ?", ctx.getArg("deptno"));
}
}