iBatisでは、行データをハンドリングするハンドラを
指定することができます。
com.ibatis.sqlmap.event.RowHandler
RowHandlerはインターフェースとなっており、
void handleRow(Object obj);
というメソッドが一つだけ定義されています。
このメソッドに渡ってくる引数が行データです。
ハンドラ付きでsqlMapを実行するには、SqlMapClientの以下のメソッドを
使用します。
void queryWithRowHandler(String, Object, RowHandler);
RowHandlerの実装クラスを作成するのは簡単なのですが、
問題は、このメソッドの返り値がvoidとなっている点です。
結果を受け取りたい場合は、ハンドラ内で値を保持して返す必要があります。
今回は、行データをロギングしながら、リストに保持するハンドラを作成してみます。
一つのハンドラで作成してもよかったのですが、面白くないので責任毎にクラスを
分けてみました。
以下サンプルです。
[ロギングを担当するRowHanler]
// vim:set ts=4 sw=4 et ws is nowrap ft=java: package gsf.samples.ibatis.sample007; import com.ibatis.sqlmap.client.event.*; import org.apache.commons.logging.*; /** * 行データをロギングしていくRowHandlerの実装クラス.<br/> * * @author gsf_zero1 * * @see com.ibatis.sqlmap.client.event.RowHandler * */ public class LoggingRowHandler implements RowHandler{ /** ログオブジェクト */ private static final Log log = LogFactory.getLog(LoggingRowHandler.class); /** * コンストラクタ.<br/> * */ public LoggingRowHandler(){ // nop; } /** * 行をハンドリングする.<br/> * このメソッドは、引数で指定された<br/> * 行データをログ出力します.<br/> * * @param row 行データ * * @see com.ibatis.sqlmap.client.event.RowHandler#handleRow(java.lang.Object) * */ public void handleRow(Object row){ log.info(row); } }
[行データの保持を担当するRowHandler]
// vim:set ts=4 sw=4 et ws is nowrap ft=java: package gsf.samples.ibatis.sample007; import java.util.*; import com.ibatis.sqlmap.client.event.*; /** * 行データを内部でリストとして保持するRowHandlerの実装クラス.<br/> * * @author gsf_zero1 * * @see com.ibatis.sqlmap.client.event.RowHandler * */ public class ListStoredRowHandler<T> implements RowHandler{ /** 行データのリスト */ private List<T> rowList; /** * コンストラクタ.<br/> * */ public ListStoredRowHandler(){ this.rowList = new ArrayList<T>(); } /** * 行データをハンドリングする.<br/> * このメソッドは、引数で渡された行データを<br/> * 内部のリストに保持していきます.<br/> * * @param row 行データ * * @see com.ibatis.sqlmap.client.event.RowHandler#handleRow(java.lang.Object) * */ public void handleRow(Object row){ this.rowList.add((T) row); } /** * 行データを取得する.<br/> * * @return 行データのリスト * */ public List<T> getRowList(){ return this.rowList; } }
[複数のRowHandlerの実行を担当するRowHandler]
// vim:set ts=4 sw=4 et ws is nowrap ft=java: package gsf.samples.ibatis.sample007; import java.util.*; import com.ibatis.sqlmap.client.event.*; /** * 複数のRowHandlerをチェーンして実行するRowHandlerの実装クラス.<br/> * * @author gsf_zero1 * * @see com.ibatis.sqlmap.client.event.RowHandler * */ public class ChainedRowHandler implements RowHandler{ /** 内部で保持しているハンドラのリスト */ private List<RowHandler> handlers; /** * コンストラクタ.<br/> * */ public ChainedRowHandler(){ this.handlers = new ArrayList<RowHandler>(); } /** * ハンドラを追加する.<br/> * * @param handler ハンドラ * */ public void addRowHandler(RowHandler handler){ this.handlers.add(handler); } /** * 行データをハンドリングする.<br/> * このメソッドは、内部で保持しているハンドラのリスト<br/> * からハンドラを取り出し、順にhandleRowメソッドをコール<br/> * していきます.<br/> * * @param row 行データ * * @see com.ibatis.sqlmap.client.event.RowHandler#handleRow(java.lang.Object) * */ public void handleRow(Object row){ for(RowHandler aHandler : this.handlers){ aHandler.handleRow(row); } } }
[SqlMapの実行を担当するクラス]
// vim:set ts=4 sw=4 et ws is nowrap ft=java: package gsf.samples.ibatis.sample007; import java.sql.*; import gsf.interfaces.sqlmap.*; import com.ibatis.sqlmap.client.*; /** * Sample007にて、SqlMapの実行を担当するクラス.<br/> * * @author gsf_zero1 * * @see gsf.interfaces.sqlmap.SqlMapClientExecutor * */ public class Sample007SqlMapClientExecutor implements SqlMapClientExecutor{ /** * SqlMapを実行する.<br/> * * @param sqlMap SqlMapClientオブジェクト * * @return 結果 * * @throws SQLException SQL処理実行中にエラーが発生した場合 * * @see gsf.interfaces.sqlmap.SqlMapClientExecutor#execute(com.ibatis.sqlmap.client.SqlMapClient) * */ public Object execute(SqlMapClient sqlMap) throws SQLException{ ChainedRowHandler chainedHandler = new ChainedRowHandler(); LoggingRowHandler loggingHandler = new LoggingRowHandler(); ListStoredRowHandler<Sample007TestTable> listStoredHandler = new ListStoredRowHandler<Sample007TestTable>(); chainedHandler.addRowHandler(loggingHandler); chainedHandler.addRowHandler(listStoredHandler); sqlMap.queryWithRowHandler("sample007FindAll", null, chainedHandler); return listStoredHandler.getRowList(); } }
[データクラス]
// vim:set ts=4 sw=4 et ws is nowrap ft=java: package gsf.samples.ibatis.sample007; import java.io.*; import java.util.Date; import java.sql.*; import org.apache.commons.lang.builder.*; /** * SAMPLE007_TEST_TABLEに対応するドメインクラス.<br/> * * @author gsf_zero1 * */ public class Sample007TestTable implements Serializable{ /** ID */ private Integer id; /** DATA1 */ private Integer data1; /** DATA2 */ private String data2; /** DATA3 */ private Date data3; /** DATA4 */ private Timestamp data4; /** * コンストラクタ.<br/> * */ public Sample007TestTable(){ // nop; } /** * Get id. * * @return id as Integer. */ public Integer getId(){ return this.id; } /** * Set id. * * @param id the value to set. */ public void setId(Integer id){ this.id = id; } /** * Get data1. * * @return data1 as Integer. */ public Integer getData1(){ return this.data1; } /** * Set data1. * * @param data1 the value to set. */ public void setData1(Integer data1){ this.data1 = data1; } /** * Get data2. * * @return data2 as String. */ public String getData2(){ return this.data2; } /** * Set data2. * * @param data2 the value to set. */ public void setData2(String data2){ this.data2 = data2; } /** * Get data3. * * @return data3 as Date. */ public Date getData3(){ return this.data3; } /** * Set data3. * * @param data3 the value to set. */ public void setData3(Date data3){ this.data3 = data3; } /** * Get data4. * * @return data4 as Timestamp. */ public Timestamp getData4(){ return this.data4; } /** * Set data4. * * @param data4 the value to set. */ public void setData4(Timestamp data4){ this.data4 = data4; } /** * オブジェクトの文字列表現を返す.<br/> * * @return 文字列表現 * */ @Override public String toString(){ return new ReflectionToStringBuilder(this).toString(); } }
[動作確認クラス]
// vim:set ts=4 sw=4 et ws is nowrap ft=java: package gsf.samples.ibatis.sample007; import java.util.*; import gsf.utils.sqlmap.*; /** * iBatis Sample 007の動作確認用のクラス.<br/> * * @author gsf_zero1 * */ public class IBatisSample007{ /** * アプリケーションエントリポイント.<br/> * * @param args 起動時引数. * */ public static void main(String[] args){ List<Sample007TestTable> result = (List<Sample007TestTable>) SqlMapUtils.executeNoTransaction( new Sample007SqlMapClientExecutor(), "execute"); System.out.println("\n\n"); for(Sample007TestTable obj : result){ System.out.println(obj); } } }
[SqlMap設定ファイル]
<?xml version="1.0" encoding="Windows-31J"?> <!-- vim:set ts=4 sw=4 et ws is nowrap ft=xml: --> <!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd"> <sqlMap namespace="RowHandler"> <typeAlias alias="Sample007TestTable" type="gsf.samples.ibatis.sample007.Sample007TestTable"/> <select id="sample007FindAll" resultClass="Sample007TestTable"> select id ,data1 ,data2 ,data3 ,data4 from SAMPLE007_TEST_TABLE order by id </select> </sqlMap>
てな感じです。