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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40285302/article/details/79949214

导读: 
在实际开发过程中遇到需要批量插入、批量更新、批量删除等操作,纠结于是在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>
阅读更多

没有更多推荐了,返回首页