web-dev-qa-db-ja.com

MyBatis foreachでHashMapを反復処理する方法は?

Mybatisで以下のようなSQLを作成しようとしています。

SELECT COL_C
FROM TBLE_1
WHERE (COL_A, COL_B) in ( ('kp','kar'),('srt','sach'));

そして私の入力パラメータタイプはHashMapです。マッパーxmlファイルからSQLを生成するにはどうすればよいですか。以下のコードは、マップがnullと評価されたことを示す例外をスローします。

<select id="selectCOLC" parameterType="Java.util.HashMap" resultType="String">
    SELECT COL_C
    FROM TBLE_1
    WHERE (COL_A, COL_B) in 
    <foreach item="item" collection="#{map.keySet()}" open="((" separator="),(" close="))">
        #{item},#{item.get(item)}
    </foreach>
</select>

他のアプローチの1つは、キー値フィールドを持つクラスを作成し、オブジェクトのリストを作成してから、次のようにparameterTypelistとして渡すことです。

<select id="selectCOLC" parameterType="list" resultType="String">
        SELECT COL_C
        FROM TBLE_1
        WHERE (COL_A, COL_B) in 
        <foreach item="item" collection="list" open="((" separator="),(" close="))">
            #{item.getKey()},#{item.getVal()}
        </foreach>
    </select>

しかし、最初のアプローチでマッパーを機能させる方法はありますか?クエリをunionに変更する以外

8
Karthik Prasad

このソリューションはバージョン3.2以降は機能しません-詳細については 問題#208を参照してください

最後に、HashMapのソリューションがあります

反復可能にするためにentrySet()を使用する必要があります

<select id="selectCOLC" parameterType="map" resultType="kpMap">
    SELECT COL_C
    FROM TBLE_1
    WHERE (COL_A, COL_B) in 
    <foreach item="item" collection="entries.entrySet()" open="((" separator="),(" close="))">
        #{item.key},#{item.value}
    </foreach>
</select>

パラメータ名が挿入されていなかったため、@Paramアノテーションが追加されました。

したがって、マッパーインターフェイスは次のようになります。

List<TblData> selectCOLC(@Param("entries")
            HashMap<String, String> entries)
14
Karthik Prasad

これは私のプロジェクトの例であり、正常に機能します

<select id="getObject" parameterType="Map" resultType="hashmap">    
    select * from TABL where 
    <foreach  collection="dataMap"  index="key" item="value"  open=""  separator=" and "  close="">
        #{key}=#{value}
    </foreach>
</select>
13
foghost

最初の例では、mybatisはキー「map」を持つparameterMapのエントリを探しています。あなたが実際にparameterMapのキーセットを反復しようとしているのではないかと思います。キー「map」を使用してパラメータマップ内にマップをネストした場合、それは機能するはずです。

2番目の例では、getKeyとgetValueを提供するHashMap.entrySet()を渡すことができるはずです。

1
Brian

Mybatis 3.5のユーザーとして、私はこれを経験しました。

残念ながら、ここに投稿された解決策はどれも私にはうまくいきませんでしたが、これはうまくいきます:

_<foreach collection="_parameter.entrySet()" index="key" item="element" separator=",">
    MY_COLUMN = #{key} AND MY_OTHER_COLUMN = #{element}
</foreach>
_

だから、私の場合collection="_parameter.entrySet()"トリックをしました!

さらに、noneparameterTypeに関する指定が必要でした。

0
Arcones