EzJDBCへの質問と返答/備考録
社内からEzJDBCの質問があったので、質問と回答をとめたものを備考録としてメモメモします。
Q1.EzJDBC#relationする場合、個別にORDER BY句オプションが追加できればいいと思います。
A1.個別にORDER BY句オプションというのは、以下の様なことでしょうか?
親(CUSTOMER)子(ORDER)孫(ORDER_ITEM)のテーブルを結合した時に、それぞれの並び順を指定
するを可能にするという内容であれば、以下のように指定することが可能です。
CUSTOMER CUS = new CUSTOMER();
Listlist = EzJDBC.froms(CUS).join(CS.ODR.ODI)
.where(CUS.name.like("TAKA%"))
.orderBy(CUS.name.asc(), ORD.orderDate.desc(), ORD.no.asc())
.find(Customer.class);
Q2.複数レコード結果が返るSQLには、ORDER BY句オプションは必須かと。
A2.なるほど検討の価値ありですね。
その場合は、自動orderByセットを解除する機能も一緒に持とうかと思います。
1.デフォ設定の場合は、EzJDBC#relationメソッドを利用した場合にorderByメソッドの指定
がなかった時は、自動で親子孫...テーブルのプライマリキーをORDER BY句に設定する。
このデフォ設定も「EzJDBC.properties」の下記の設定で切り替え可能。
# ORDER BY句自動設定有無(true:自動セットon, false:自動セットoff)
ORDERBY_AUTO_SET=true
CUSTOMER CUS = new CUSTOMER();
Listlist = EzJDBC.froms(CUS).join(CS.ODR.ODI)
.where(CUS.name.like("TAKA%"))
.orderBy(false)
.find(Customer.class);
Q3.A2の回答についてはある意味良いとは思いますが、全て自動だと、あまりSQLを意識しなくなり開発者にとって危険だと思いますが。
A3.ここが鬼門ですね。
もう一つ案があるのですが、orderByメソッドを呼び出さないとfind系メソッドが
呼び出さないようにするとか!
方法はいたって単純なのですが、EzJDBC#orderByで帰ってくるインターフェースのみ
find系メソッドが存在するとか。
1.JDBC1インターフェースにはfind系メソッドが存在しない
JDBC1 jdbc1 = EzJDBC.froms(CUS).join(CS.ODR.ODI)
2.JDBC2インターフェースはfind系メソッドが存在する
JDBC2 jdbc2 = EzJDBC.froms(CUS).join(CS.ODR.ODI).orderBy(...)
Q4.A3はORDER BY句のクセをつけるためにはいいですね。1件しか返ってこないSQLの場合は微妙かもですけど。
A4.そうですね(^^;)
ただし、EzJDBC#from#join#relationの場合は、メイン(Root)テーブル以外のテーブルへの
order by句は意味をなすので必要かなと。
EzJDBC#findSingleメソッドは、orderByメソッドを呼び出さなくても良いようにするか(・・?
微妙ですね。EzJDBC#findSingleは、結果が複数件であっても最初の1件を取得するので、
orderByの意味は存在するので…検討事項とします。
Q5.個人的には(DB2で言えば)fetch first句は欲しいですが、そこまで行くとSQL手書きですよね。
使い道としては、バッチ系の大量更新処理で、、、
1.N件単位にfetchで抽出結果を制限して取得
2.UPDATE or DELETE処理
3.コミット
条件に該当する結果がなくなるまで繰り返し、エラーが発生した場合でも処理単位にリカバリーする
必要のない更新処理(再編成-削除とか)では絶大な威力を発揮します。
A5.EzJDBCで上記のことを行う場合は、2通りの方法が用意されています
1.ページング機能による実装(EzJDBC#limitメソッドとEzJDBC#offsetメソッド)
// トランザクション開始
EzTx.begin();
// 取得するレコード数、カーソルのポインタ
int n=10; int p= 1;
CUSTOMER CS = new CUSTOMER();
// テーブルを照会
EzJDBC jdbc = EzJDBC.froms(CS).where(CS.name.eq("TAKAHASHI")).limit(n);
Listlist = null;
while(list = jdbc.offset(p).find(Customer.class)).size() > 0) {
for(Customer c:list) {
c.name="高橋";
EzJDBC.to(CS).update(c);
}
EzTx.commit();
// offset加算
p = p+n;
}
// トランザクション終了
EzTx.end();
2.イテレート機能による実装(EzJDBC#iteretorメソッド)
// トランザクション開始
EzTx.begin();
// 更新系SQLを10回発行する毎にcommitを行う設定
EzTx.setCommitCount(10);
CUSTOMER CS = new CUSTOMER();
// 条件とマッチするデータを10(n)件毎取得するEzJDBC
JDBCIteratorjdbcIterator = EzJDBC.froms(CS)
.where(CS.name.eq("TAKAHASHI")).iterator(Customer.class);
while(jdbcIterator.hasNext()) {
Customer c = jdbcIterator.next();
c.name="高橋";
EzJDBC.to(CS).update(c);
}
// トランザクション終了
EzTx.end();
1と2の違いは、1はSQLが複数回発行されますが、2の方法は1回のみですということです...(^^)
用途によって使いわければよいかと思います。
但しレスポンスは圧倒的に2の方法が良いです。。。