帳モメのotanuft

Stay hungry, stay foolish.

iBATIS: SqlMap remapResults

問い合わせの結果、カラムが動的に変化するSQLを使用する場合、

remapResults="true"を各ステートメント

追加しなければならない。

例えばテーブルが動的に変わるSQLなどを使用する場合。

下記のSqlMapを定義した場合

<select id="selectTable" resultClass="java.util.HashMap">

SELECT * FROM $value$

</select>

List l = queryForList("selectTable","TABLE_A");

List l2 = queryForList("selectTable","TABLE_B");

上記のコードで実際に使用すると、2番目の呼び出しで

java.sql.SQLException: Column not found:

TABLE_AとTABLE_Bで問い合わせ結果のカラムに差がある場合にスローされる。

iBATIS内部では最初の問い合わせの時に、マッピング情報をキャッシュし

マッピングの効率を上げているため2度目の呼び出しでもキャッシュを使用して

マッピングしようとするため起きている。

そのため、キャッシュを使わないように問い合わせを行うたびにマッピング情報を

更新するためにremapResults="true"を使用する。

remapResultsを使用できるステートメントは、DTDによると

・statement

・select

上記の例ではテーブルを明示的に変更しているのがわかるので、問題になることは少ないが

iBATISのテストケースにある

<select id="testRemappableResults" parameterClass="int" resultClass="testdomain.Account">

select

<isNotEqual compareValue="77">

ACC_ID as id,

</isNotEqual>

ACC_FIRST_NAME as firstName,

ACC_LAST_NAME as lastName,

ACC_EMAIL as emailAddress

from ACCOUNT

<isEqual compareValue="77">

where ACC_ID = 2

</isEqual>

<isNotEqual compareValue="77">

where ACC_ID = #value#

</isNotEqual>

</select>

のような場合は注意が必要で同じresultClassを使用し、同じテーブルを使用しているので

結果カラム増減やカラム名の変化はわからない。

最初にACC_IDのカラムが使用されないパターンの場合、remapResults=true

設定されていない場合、testdomain.Accountのidプロパティにはどの条件でも値がセットされない。