您的位置:首页 > 其它

关于Mybatis中foreach的用法以及与service中循环调用dao层中的差异

2016-05-26 18:35 465 查看
导读:

在实际开发过程中遇到需要批量插入、批量更新、批量删除等操作,纠结于是在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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: