mybatis foreach標(biāo)簽

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'. 這里使用了一些屬性:

  1. collection="list", 后面會(huì)解釋,當(dāng)你的參數(shù)是List時(shí),這個(gè)地方值也必須是list
  2. item="prop", item表示list中的每一個(gè)元素,這里list里放的是InstanceProperty,因此可以通過(guò)'#{prop.name}' 訪問(wèn)屬性。
  3. separator=",", 設(shè)置foreach生成的多條記錄之間的分割符。

foreach的其他屬性

  1. 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è)例子。
  1. 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:

  1. 傳遞List類型的參數(shù),則會(huì)在M里有一條 {"list" : properties },所以此時(shí)collection設(shè)置為“l(fā)ist”就等于拿出M中key="list"的value,然后遍歷它。
  2. 傳遞數(shù)組類型參數(shù), 則會(huì)在M里有一條{"array", properties},所以此時(shí)需要設(shè)置collection="array".
  3. 傳遞Map類型的參數(shù), 不會(huì)做任何轉(zhuǎn)換,假設(shè)你的Map類型的參數(shù)中包含的是{"china" :"beijing", "usa":"w.d.c"}, 那么M中就有兩條映射:{"china" :"beijing", "usa":"w.d.c"} 。
  4. 如果傳入的是一個(gè)bean,那么的bean中的屬性作為key,屬性值作為value放到M中。
  5. 如果傳入的是一個(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容