1. mapper接口定義如下:
public interface InstancePropertiesMapper {
void addProperties(List<InstanceProperty> properties);
}
-----------------------------------------------------------
public class InstanceProperty {
private String name;
private Long instanceId;
}
此處希望addProperties
能一次性往表里插入多條記錄,插入的信息以List<InstanceProperty> properties
列表保存乘寒。
假設(shè)properties列表中保存的數(shù)據(jù)如下:
[
{"eric", 0},
{'john', 1},
{"sam", 2}
]
需要達(dá)到的效果和下面sql類似:
insert into properties(name, instance_id) values("eric", 0) ,("john",1),("sam",2);
這樣的效果.
對(duì)應(yīng)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>
標(biāo)簽遍歷參數(shù)'properties'. 這里使用了一些屬性:
- collection="list", 后面會(huì)解釋,當(dāng)你的參數(shù)是List時(shí)吧慢,這個(gè)地方值也必須是list
- item="prop", item表示list中的每一個(gè)元素,這里list里放的是InstanceProperty马靠,因此可以通過(guò)'#{prop.name}' 訪問(wèn)屬性。
- separator=",", 設(shè)置foreach生成的多條記錄之間的分割符看蚜。
foreach的其他屬性
- open叫搁,close,定義如何將foreach所有記錄包圍起來(lái)供炎,比如如果如同下面這樣寫:
<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)};
當(dāng)然這樣沒有任何意義渴逻,是一條錯(cuò)誤的sql語(yǔ)句,這里僅僅是為了舉個(gè)例子音诫。
- index
當(dāng)foreach遍歷的數(shù)list或=者數(shù)組時(shí)惨奕,index代表就是下標(biāo),foreach遍歷map時(shí)index代表key竭钝,此時(shí)item表示value墓贿。
關(guān)于collection屬性
首先需要知道m(xù)ybatis怎么處理參數(shù)的,傳遞給XXXMapper接口方法的所有參數(shù)會(huì)被放到一個(gè)map中(后面叫這個(gè)map為M)蜓氨,假設(shè)存在參數(shù)properties:
- 傳遞List類型的參數(shù)聋袋,則會(huì)在M里有一條 {"list" : properties },所以此時(shí)collection設(shè)置為“l(fā)ist”就等于拿出M中key="list"的value穴吹,然后遍歷它幽勒。
- 傳遞數(shù)組類型參數(shù), 則會(huì)在M里有一條{"array", properties}港令,所以此時(shí)需要設(shè)置collection="array".
- 傳遞Map類型的參數(shù)啥容, 不會(huì)做任何轉(zhuǎn)換,假設(shè)你的Map類型的參數(shù)中包含的是{"china" :"beijing", "usa":"w.d.c"}, 那么M中就有兩條映射:{"china" :"beijing", "usa":"w.d.c"} 顷霹。
- 如果傳入的是一個(gè)bean咪惠,那么的bean中的屬性作為key,屬性值作為value放到M中淋淀。
- 如果傳入的是一個(gè)基本類型變量遥昧,那么M中就會(huì)存在一條key是變量名,value是變量值(由于jdk7之前反射無(wú)法拿到參數(shù)名,可以使用下面介紹的注解)炭臭。
綜上永脓,collection能夠指定的值就是M中最終存在的key,<foreach>標(biāo)簽從M中拿到key的value鞋仍,然后遍歷value常摧,所以這個(gè)value必須是能夠被遍歷的對(duì)象。
以上都是假設(shè)你沒有在Mapper的接口方法上使用mybatis提供的注解org.apache.ibatis.annotations.Param
注解參數(shù)名時(shí)collection的默認(rèn)值威创,如果你在參數(shù)上使用了這個(gè)注解落午,那么最終M中的key是注解名,value是參數(shù)值肚豺,如下:
public interface PersonMapper {
void insertPerson1(@Param("map") Map<String, Person> persons);
}
使用注解時(shí)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", 相當(dāng)于拿到M.get("map")的值,也就是persons详炬,
然后遍歷persons盐类, 遍歷的結(jié)果是index是persons的key, item是對(duì)應(yīng)的value