S2JDBCでHibernateのiterate()相当の処理
S2Jdbc で1件ずつフェッチできれば、それで決定なのになぁ。
大量データを検索して処理したい時に、List
だとOutOfMemoryErrorが発生させてしまう場合がある。1行づつデータを取ってくるIteratorもほしい気がする。例えばこんな感じ。
S2JDBCでHibernateのiterate()やscroll()のように1件ずつ処理したい場合ですが、そういうときは最初にidのリストや配列を取得して、そのあと1件ずつ取得して処理するといいと思います。
1+NのSELECTが発生してパフォーマンスが悪いんじゃん?と思うかもしれませんが、S2JDBCは同じトランザクション内でPreparedStatementをキャッシュしているのでパフォーマンスは結構いいです。N件のSELECTはすべて同じPreparedStatementで処理されることになります。
コードはこんな感じになります。
テストコード
public void testIterate() throws Exception { // 1件目のSQL List<Integer> idList = jdbcManager .selectBySql( Integer.class, "select employee_id from employee where employee_id < 100") .getResultList(); for (Integer id : idList) { // N件のSQL Employee e = jdbcManager.from(Employee.class).id(id).getSingleResult(); } }
実行されるSQL
select employee_id from employee where employee_id < 100 SELECT t1_.employee_id, t1_.employee_no, t1_.employee_name, t1_.manager_id, t1_.hiredate, t1_.salary, t1_.department_id, t1_.address_id, t1_.version FROM employee t1_ WHERE t1_.employee_id = 1 SELECT t1_.employee_id, t1_.employee_no, t1_.employee_name, t1_.manager_id, t1_.hiredate, t1_.salary, t1_.department_id, t1_.address_id, t1_.version FROM employee t1_ WHERE t1_.employee_id = 2 ...(idの値が違うだけのSQLがつづく)
たいした手間ではないですが、IDのリストを取得するクエリがちょっと面倒くさいと感じちゃうかもしれませんね。
Seasarの次のバージョン2.4.19では、専用のiterate()処理が含まれるかもしれないです。