關於Mybatis中foreach的用法以及與service中循環調用dao層中的差異

導讀:
在實際開發過程中遇到需要批量插入、批量更新、批量刪除等操作,糾結於是在service層中直接調用dao層的方式還是直接使用Mybatis中的標籤,因此特地做了一個實驗。
做兩個批量插入操作,一個是在service層中循環調用dao層的方法,另一個是在Mybatis中使用標籤做插入操作。
代碼如下:

service層對應的代碼:

 public void doSave() {
        for (int i = 0; i < 9999; i++) {
            Orders orders = new Orders();
            orders.setOrderCode("test" + i);
            ordersMapper.insert(orders);
        }

    }

Mybatis xml文件中對應的代碼:

 <insert id="insert" parameterType="com.cn.lt.front.order.entity.Orders">
    insert into orders (order_id, order_code, cancel_reason,
  )
    values (#{orderId,jdbcType=INTEGER}, #{orderCode,jdbcType=VARCHAR}
    )
 public void doSaveTwo(List<Orders> list) {
        ordersMapper.insertTest(list);
    }

Mybatis對應的xml文件

<insert id="insertTest">
            insert into orders (order_id, order_code )
            values
        <foreach collection="list" item="item" index="index" separator=",">
            (#{item.orderId}, #{item.orderCode})
        </foreach>
</insert>

經過測試發現,在service中做for循環log日誌如下

2016-05-26 16:29:44[DEBUG][SqlSessionUtils]-Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7556b510] from current transaction
2016-05-26 16:29:44[DEBUG][insertSelective]-ooo Using Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@6b6ea54]
2016-05-26 16:29:44[DEBUG][insertSelective]-==>  Preparing: insert into orders ( order_code, update_date, create_date ) values ( ?, now(), now() ) 
2016-05-26 16:29:44[DEBUG][insertSelective]-==> Parameters: test9998(String)
2016-05-26 16:29:44[DEBUG][SqlSessionUtils]-Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7556b510]

結果顯示,每次都需要獲取數據庫鏈接
而在Mybatis的xml文件中做foreachx顯示

Preparing: insert into orders (order_id, order_code ) values (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?) , (?, ?)  test1327(String), null, test1328(String), null, test1329(String), null, test1330(String), null, test1331(String), null, test1332(String), null, test1333(String), null, test1334(String), null, test1335(String), null, 

由此猜測Mybatis底層可能對list進行了特殊處理,應該類似調用jdbc的insert,對插入的數據進行拼裝。
因此有必要去查看下源碼:
http://www.blogjava.net/xmatthew/archive/2011/08/31/355879.html 分析的很到位。
使用foreach標籤需要注意一下:
屬性有:collection、item、index、open、separator、close.
item:集合中每個元素迭代的別名。
collection:集合
index:迭代過程中迭代的位置。
open:表示以什麼爲開頭。
separator:表示以什麼符號作爲分隔符。
close:表示以什麼爲結束。
在需要傳入集合的時候需要加上註解@param(value=”“)這樣就能傳入多個參數。

例子1:

public User findByName(@Param(value="aa"));
public List<User> select(@Param(value="ids")List<Long> ids);

xml中代碼

<select id="select" resultType="User">
    select * from user a
    where
    a.id in
    <foreach collection="ids" item="id" open="(" separator="," close=")">
        #{id}
    </foreach>
</select>

例子2

public List<User> select(@Param(value="ids")List<Long> ids, @Param(value="status")String status);

XML中代碼如下

<select id="select" resultType="User">
    select * from user a
    where
    a.id in
    <foreach collection="ids" item="id" open="(" separator="," close=")">
        #{id}
    </foreach>
    AND
    a.status=#{status}
</select>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章