如何在MyBatis foreach中迭代HashMap?

时间:2013-08-22 19:09:36

标签: java sql foreach mybatis

我正在尝试在mybatis中生成如下所示的sql。

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

我的输入参数类型是HashMap。现在如何从mapper xml文件生成SQL。下面的代码抛出异常,说map被评估为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>

另一种方法是创建一个包含键值字段的类,创建一个对象列表,然后将parameterType作为list传递,如下所示。

<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>

但是我的第一种方法有没有办法让我的mapper工作?而不是将查询更改为union

4 个答案:

答案 0 :(得分:14)

此解决方案自版本3.2起无效 - 请参阅Issue #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>

另一个Isue我面临的参数名称没有被注入,因此添加了@Param注释

因此mapper界面如下所示。

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

答案 1 :(得分:12)

这是我项目中的一个示例,它运行正常

<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>

答案 2 :(得分:1)

在你的第一个例子中,mybatis正在使用键“map”在parameterMap中查找一个条目。我怀疑你实际上是在尝试迭代parameterMap的键集。如果使用键“map”在参数映射中嵌套地图,它应该可以工作。

在第二个例子中,您应该只能传递提供getKey和getValue的HashMap.entrySet()。

答案 3 :(得分:0)

作为mybatis 3.5的用户,我遇到了这个问题。

不幸的是,这里发布的所有解决方案都不适合我,但这确实可行:

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

因此,以我为例, collection="_parameter.entrySet()" 起到了作用!

此外,需要有关 parameterType 规范。