MyBatisでforeachを使用して動的SQLを生成する

MyBatisiBATIS(MyBatis)

MyBatisでforeachを使用して動的SQLを生成する

MyBatisでforeachを使用して動的SQLを生成する事が出来ます。 よくIN句の中で使用されます。

<select id="selsectA" parameterType="java.util.List" resultType="String">
  SELECT ITEM_NAME
  FROM TBL
  WHERE ITEM_CD in  
    <foreach item="item" open="(" close=")" collection="dataList" separator=",">
      #{item}
    </foreach>
</select>

foreachなのでそのまま、dataListをループします。

その際、openで「(」、closeで「)」、各リスト事の区切り文字は「,」なので以下のようなSQLコードが生成されます。

('01','02','03')

バッチなどならバルクインサートで使用したりします。Oracleの場合は、INSERT ALLも参照してください。以下はDB2で確認した例です。

<insert id="insertA" parameterType="java.util.List">
  INSERTT INTO テーブル名
    (COL1,COL2)
    VALUES
    <foreach item="item" collection="list" open="" close="" separator=",">
    (
      #{item.id, jdbcType=INTEGER},
      #{item.name, jdbcType=VARCHAR}
    )
    </foreach>
</insert>

collection=”list”としていますが、java.util.Listを継承するクラスの場合は、collection=”list”と記述します。(インスタンス名がlistでなくても)

配列の場合は、collection=”array”と記述します。

foreachのindexの使い方はこちらを参照ください。ちなみにindexの基底値は0です。

引数にListを渡すのではなく、Beanを渡す場合、getterメソッドが勝手に呼ばれます。

<select id="SQLID" parameterType="jp.co.confrage.SampleBean" resultType="String">
SELECT ID
FROM   ${schema}.TBL
WHERE    YYYY <![CDATA[<=]]> #{yyyy}
</select>

getSchemaメソッド、getYyyyメソッドが実行されます。

Beanを詰めたListをparameterTypeで渡した場合もgetterは実行されました。

List<Bean> list = new ArrayList<Bean>();

Beanのスーパークラスのプロパティのgetterも実行されました。

以下のようなBeanの構成の場合です。

public class Bean extends SuperBean {
…
…

ただし、プロパティがstaticメンバークラスで、foreach内で使用しようとして見た場合は以下エラーが出ました。

Caused by: org.apache.ibatis.builder.BuilderException: Error evaluating expression 'user.innerClass'. Cause: org.apache.ibatis.ognl.NoSuchPropertyException: jp.co.confrage.SampleBean.innerClass

そんなプロパティありません、ってことでしょうか? 以下のように使用しようとした時です。(かなり割愛しています)

<foreach item="user" collection="list" separator=",">
${user.innerClass}
</foreach>

staticメンバークラスは取得出来ないのかと思っていましたが、そんなことはなく、getterが正しくキャメルケースで記述されていなかった為、動作してくれなかったのが原因でした。

getDBSchmaと言うメソッド名が原因でした。

正しくgetDbSchemaにするとgetterが呼ばれました。 なので、以下のような記述方法も可能です。

<foreach item="user" collection="list" separator=",">
${user.dbSchema.property}
</foreach>

コメント

タイトルとURLをコピーしました