SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

iBATISを使ったO/RマッピングによるDBアクセスの実例

iBATISを使ったO/RマッピングによるDBアクセスの実例 3

Handlerクラスを使ったiBATISの機能拡張

  • X ポスト
  • このエントリーをはてなブックマークに追加

RowHandlerを使ったCSV出力

 RowHandlerは1行分の検索結果を扱うためのインターフェースです。このインターフェースを実装することで、検索結果から任意の処理を行うことができます。

 大量の検索結果をCSVデータとして出力することを考えてみます。iBATISは検索結果をListデータとして返してくれます。例えば1千万件もあるデータをqueryForListで取得すると、1千万件もの検索結果を保持するListがJavaのオブジェクトして生成されてしまいます。このListを全件走査してCSVファイルを出力した場合、Listは単なる中間データとして存在するだけです。一時的とはいえ大量のメモリを消費してしまうことが予想されます。

 このようなケースでは、RowHandlerを使って大量データを1件ずつCSVファイルに出力すると効果的です。DEPT表の全件をCSV出力してみます。

検索結果を受け取るDeptオブジェクト

Dept.javaの抜粋
public class Dept {
  private int deptno;
  private String dname;
  private String location;
  public int getDeptno() {
    return deptno;
  }
  public void setDeptno(int deptno) {
    this.deptno = deptno;
  }
  //以下同様なsetter,getter 省略
}

SqlMap

SqlMap-Custom.xmlの抜粋
<!-- CSV出力用 -->
<select id="csvData" resultClass="examples.dto.Dept">
  SELECT DEPTNO, DNAME, LOC as location FROM DEPT
  ORDER BY DEPTNO desc
</select>

 SqlMapの記述やBeanの準備は通常の検索と同じです。次にRowHandlerを作成します。

RowHandler

 RowHandlerを自作する場合は、RowHandlerインターフェースを実装します。RowHandlerインターフェースはただ1つのhandleRowメソッドの実装を要求します。

DeptオブジェクトをCSV出力するためのRowHandler
public class CsvRowHandler implements RowHandler {
  PrintWriter out;
  /**
   * 出力ファイルを指定してCSVRowHandlerを生成する
   * @param outputFile  出力ファイル
   */
  public CsvRowHandler(File outputFile) throws IOException {
    out = new PrintWriter(new FileWriter(outputFile)); 
  }
  /**
   * 1行を処理する
   */
  public void handleRow(Object value) {
    Dept dept = (Dept)value;
    out.print(dept.getDeptno());
    out.print(",");
    out.print(dept.getDname());
    out.print(",");
    out.print(dept.getLocation());
    out.println();
  }
  /**
   * ファイルをクローズする。
   */
  public void close(){
    out.close();
  }
}

 コンストラクタでファイル名を指定し、ファイルをオープンします。

 handleRowメソッドは、このRowHandlerが使用される場合に呼び出されます。N件の検索結果を返すSEELCT文では、handleRowメソッドがN回呼び出されます。引数valueには、SqlMapで定義されたResultClassのオブジェクトが設定されています。つまり今回の例ではDeptオブジェクトが渡されます。

実行プログラム

Sample12_RowHandler.javaの抜粋
//CSV出力用RowHandlerを生成
CsvRowHandler rowHandler = new CsvRowHandler(new File("Dept.csv"));
//rowHandlerを指定してクエリーを実行
sqlMap.queryWithRowHandler("csvData", rowHandler);
//CSVファイルをクローズ
rowHandler.close();

 queryForListではなく、queryWithRowHandlerで実行します。引数で自作したRowHandlerを指定します。

 CsvRowHandlerが検索結果の1件1件をファイルに出力します。大量データであっても1件ずつ処理するのでメモリ消費量は取得件数には関係なく、どれだけの大量データを出力しても安定します。

 1行ずつ処理したい場合には、RowHandlerを使って任意のコードを記述できます。iBATISのDeveloper Guideでは1件ずつ検索しながらUPDATEを発行する例が紹介されています。

次のページ
TypeHandlerを使用した型の変換

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
iBATISを使ったO/RマッピングによるDBアクセスの実例連載記事一覧

もっと読む

この記事の著者

佐々木孝(ササキタカシ)

Javaをメインに業務システムの開発サポート、パッケージ開発、および技術研究をしています。 

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/1852 2007/11/16 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング