搜索
您的当前位置:首页正文

mybatis foreach标签

来源:二三娱乐

1. mapper接口定义如下:

public interface InstancePropertiesMapper {
    void addProperties(List<InstanceProperty> properties);
}
-----------------------------------------------------------
public class InstanceProperty {
    private String name;
    private Long instanceId;
}

此处希望addProperties能一次性往表里插入多条记录,插入的信息以List<InstanceProperty> properties列表保存。
假设properties列表中保存的数据如下:

[
{"eric", 0},
{'john', 1},
{"sam", 2}
]

需要达到的效果和下面sql类似:
insert into properties(name, instance_id) values("eric", 0) ,("john",1),("sam",2);这样的效果.
对应mapper.xml如下:

<insert id="addProperties" parameterType="java.util.List">
        INSERT INTO tdt_sync_instance_properties (name,instance_id) VALUES
        <foreach collection="list" item="prop" separator=",">
            (#{prop.name},#{prop.instance_id})
        </foreach>
        ;
    </insert>

使用<foreach>标签遍历参数'properties'. 这里使用了一些属性:

  1. collection="list", 后面会解释,当你的参数是List时,这个地方值也必须是list
  2. item="prop", item表示list中的每一个元素,这里list里放的是InstanceProperty,因此可以通过'#{prop.name}' 访问属性。
  3. separator=",", 设置foreach生成的多条记录之间的分割符。

foreach的其他属性

  1. open,close,定义如何将foreach所有记录包围起来,比如如果如同下面这样写:
<foreach collection="list" item="prop" separator="," open="{" close="}">
            (#{prop.name},#{prop.instance_id})
        </foreach>

最终生成的就是下面这样:

insert into properties(name, instance_id) values {("eric", 0) ,("john",1),("sam",2)};
当然这样没有任何意义,是一条错误的sql语句,这里仅仅是为了举个例子。
  1. index
    当foreach遍历的数list或=者数组时,index代表就是下标,foreach遍历map时index代表key,此时item表示value。

关于collection属性
首先需要知道mybatis怎么处理参数的,传递给XXXMapper接口方法的所有参数会被放到一个map中(后面叫这个map为M),假设存在参数properties:

  1. 传递List类型的参数,则会在M里有一条 {"list" : properties },所以此时collection设置为“list”就等于拿出M中key="list"的value,然后遍历它。
  2. 传递数组类型参数, 则会在M里有一条{"array", properties},所以此时需要设置collection="array".
  3. 传递Map类型的参数, 不会做任何转换,假设你的Map类型的参数中包含的是{"china" :"beijing", "usa":"w.d.c"}, 那么M中就有两条映射:{"china" :"beijing", "usa":"w.d.c"} 。
  4. 如果传入的是一个bean,那么的bean中的属性作为key,属性值作为value放到M中。
  5. 如果传入的是一个基本类型变量,那么M中就会存在一条key是变量名,value是变量值(由于jdk7之前反射无法拿到参数名,可以使用下面介绍的注解)。

综上,collection能够指定的值就是M中最终存在的key,<foreach>标签从M中拿到key的value,然后遍历value,所以这个value必须是能够被遍历的对象。

以上都是假设你没有在Mapper的接口方法上使用mybatis提供的注解org.apache.ibatis.annotations.Param注解参数名时collection的默认值,如果你在参数上使用了这个注解,那么最终M中的key是注解名,value是参数值,如下:

public interface PersonMapper {
  void insertPerson1(@Param("map") Map<String, Person> persons);
}

使用注解时M中就存在一条"map" -> persons的映射,而不是上面介绍的把persons的key,value直接方到M中

那么可以在PersonMapper.xml中:
<insert id="insertPerson1">
        INSERT INTO mybatis.person VALUES
        <foreach collection="map" index="key" item="person" separator=",">
            (#{p.name}, #{p.age})
        </foreach>
</insert>

这里collection="map", 相当于拿到M.get("map")的值,也就是persons, 
然后遍历persons, 遍历的结果是index是persons的key, item是对应的value

Top