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'. 这里使用了一些属性:
- collection="list", 后面会解释,当你的参数是List时,这个地方值也必须是list
- item="prop", item表示list中的每一个元素,这里list里放的是InstanceProperty,因此可以通过'#{prop.name}' 访问属性。
- separator=",", 设置foreach生成的多条记录之间的分割符。
foreach的其他属性
- 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语句,这里仅仅是为了举个例子。
- index
当foreach遍历的数list或=者数组时,index代表就是下标,foreach遍历map时index代表key,此时item表示value。
关于collection属性
首先需要知道mybatis怎么处理参数的,传递给XXXMapper接口方法的所有参数会被放到一个map中(后面叫这个map为M),假设存在参数properties:
- 传递List类型的参数,则会在M里有一条 {"list" : properties },所以此时collection设置为“list”就等于拿出M中key="list"的value,然后遍历它。
- 传递数组类型参数, 则会在M里有一条{"array", properties},所以此时需要设置collection="array".
- 传递Map类型的参数, 不会做任何转换,假设你的Map类型的参数中包含的是{"china" :"beijing", "usa":"w.d.c"}, 那么M中就有两条映射:{"china" :"beijing", "usa":"w.d.c"} 。
- 如果传入的是一个bean,那么的bean中的属性作为key,属性值作为value放到M中。
- 如果传入的是一个基本类型变量,那么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