SHOEISHA iD

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

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

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

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

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

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

TypeHandlerを使用した型の変換

 iBATISは、データベースのデータ型とJavaのデータ型を交換してくれます。例えばデータベースのCHAR型、VARCHAR型をJavaのString型のプロパティにセットできます。その逆も可能です。このように基本的なデータ型はiBATISの標準機能でマッピングできますが、iBATISがサポートしていないデータ型同士の変換はできません。

 TypeHandlerを使用することで、任意のデータベースデータ型→任意のJavaオブジェクト、およびその逆が可能になります。

 サンプルプログラムでは、データベースに格納された画像ファイルのイメージデータ(バイナリデータ)から、SwingのImageIconオブジェクトに交換する例を紹介します。

 サンプルは社員に対応する社員画像を一覧表示します。実行結果はこのようなイメージです。

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

EmpImage.javaの抜粋
public class EmpImage {
  private int empno;
  private String ename;
  private ImageIcon img;
  public ImageIcon getImg() {
    return img;
  }
  public void setImg(ImageIcon img) {
    this.img = img;
  }
  //以下同様なsetter,getter 省略
}

 imgプロパティはjavax.swing.ImageIcon型のプロパティです。データベースにはImageIconに相当する型はないので、通常の検索ではimgプロパティに値をセットできません。

SqlMap

SqlMap-Custom.xmlの抜粋
<!-- イメージ取得用 -->
<resultMap id="empImageMap" class="examples.dto.EmpImage">
  <result property="empno" column="EMPNO"/>
  <result property="ename" column="ENAME"/>
  <result property="img" column="IMG" 
          typeHandler="examples.ImageIconTypeHandler"/>
</resultMap>
<select id="getImage" resultMap="empImageMap">
  SELECT
     A.EMPNO,
     A.ENAME,
     B.IMG
  FROM
    EMP AS A
  INNER JOIN
    EMPIMAGE AS B
  ON
    A.EMPNO = B.EMPNO
</select>

 javax.swing.ImageIconが取得できるようにresultMapを定義します。imgプロパティのtypeHandler属性に、これから自作するImageIconTypeHandlerを指定します。

TypeHandler

 TypeHandlerはデータベースの検索結果からResultClassのオブジェクトに変換するためのクラスです。TypeHandlerを作成する際には、TypeHandlerCallbackインターフェースを実装するのが楽です。

LONGVARBINARYとImageIconを交換するTypeHandlerの抜粋
public class ImageIconTypeHandler implements TypeHandlerCallback {
  /**
   * LONGVARBINARYのイメージデータをImageIconに変換する
   */
  public Object getResult(ResultGetter getter) throws SQLException {
    byte[] imageBytes = getter.getBytes();
    if (imageBytes == null){
      return new ImageIcon();
    }
    return new ImageIcon(getter.getBytes());
  }
  /**
   * ImageIconをJPEGバイナリデータにし、LONGVARBINARYにセットする
   */
  public void setParameter(ParameterSetter setter, Object parameter)
      throws SQLException {
    //検索のみなのでサンプルでは使われていません。
  }
  public Object valueOf(String s) {
    return "";  //未実装
  }
}

 ImageIconTypeHandlerは、データベースのLONGVARBINARY型のデータから、java.swing.ImageIconオブジェクトを生成するTypeHandlerです。

 このクラスの主な役割は2つです。1つはデータベースから取得したバイナリデータをImageIconオブジェクトに変換します(DB→Java)。もう1つはJavaのImageIconオブジェクトを、JPEG形式のバイナリデータに変換し、LONGVARBINARY型の列にセットします(Java→DB)。

 getResultがデータベースからのデータをJavaオブジェクトに変換するメソッドです。ResultGetterはJDBCのResultSetに似た作りになっていて、ここからデータベースの生のデータを取得できます。取得したデータを自由に変換しJavaオブジェクトとして返却します。

 setParameterはJavaオブジェクトをデータベースにセットするためのメソッドです。ParameterSetterはJDBCのPreparedStatementに値を格納する時に似ています。今回のサンプルでは、DBの検索結果を表示するだけで更新処理はないので、setParameterは使用されません。

 valueOfメソッドは文字列表現からJavaオブジェクトに変換するためのメソッドです。

実行プログラム

Sample13_TypeHandler.javaの抜粋
//EmpImageのリストを取得
List<EmpImage> list = (List<EmpImage>)sqlMap.queryForList("getImage");
//検索結果をJFrameで表示する。
//・・・省略・・・
for (EmpImage empimage : list){
  //JLabelにImageIconと社員名をセット
  JLabel label
    = new JLabel(empimage.getEname(), empimage.getImg(), JLabel.LEFT);
  frame.getContentPane().add(label);  //JLabelを貼り付け
}
//・・・省略・・・

 Swingコンポーネントを使用して、検索結果の画像をラベルとして表示します。TypeHandlerを使用することで、あたかもデータベースにImageIconが格納されているように取得できます。

 TypeHandlerの実装は自由なので、データベースの中に格納されたファイルパスの文字列からjava.io.Fileオブジェクトを生成したり、データベースのURL文字列から、インターネット上のファイルをHTTP経由で取得し、そのリソースを保持するといったことが実装できます(当然このような事をした場合、検索パフォーマンスは低下するので用途は検討する必要があります)。

まとめ

 今回の記事では次の2つについて紹介しました。

  • RowHandlerで検索結果に対して1件ずつ任意の処理を行うことができます
  • TypeHandlerでデータベース⇔Javaオブジェクト間の自由な型交換が可能になります

 iBATISは標準のままでも便利な機能を持っていますが、機能を拡張したい場合にも柔軟に対応できます。

参考資料

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

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

もっと読む

この記事の著者

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

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

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

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

この記事をシェア

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

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング