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

原创 2018年04月15日 14:40:59

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

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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}
    )
  • 1
  • 2
  • 3
  • 4
  • 5
 public void doSaveTwo(List<Orders> list) {
        ordersMapper.insertTest(list);
    }
  • 1
  • 2
  • 3

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

经过测试发现,在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]
  • 1
  • 2
  • 3
  • 4
  • 5

结果显示,每次都需要获取数据库链接 
而在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, 
  • 1

由此猜测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);
  • 1
  • 2

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

例子2

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

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>

深度卷积神经网络及其在语音中的基本用法

-
  • 1970年01月01日 08:00

spring+mybatis通用dao层、service层的一些个人理解与实现

首先声明,本文所述只是鉴于本人在开发一些应用时的心得,仅供参考。 1、现在的绝大多数web应用,通常都以action、service、dao三层去组织代码,这样划分结构很清晰,分工明确 2...
  • acweilisky0825
  • acweilisky0825
  • 2016-07-26 11:04:36
  • 14654

使用mybatis完成通用dao和通用service

原文  http://liuyiyou.cn/2015/01/25/base-mybatis-dao/ 主题 MyBatis 概述: 使用通用dao和通用service可以减...
  • u014351782
  • u014351782
  • 2016-03-31 19:38:44
  • 4807

mybatis sql in 查询 mapper与service层写法

当查询的参数只有一个时 findByIds(List ids) 1.1 如果参数的类型是List, 则在使用时,collection属性要必须指定为 list(要是Repository 层指定参...
  • chenaini119
  • chenaini119
  • 2016-06-17 14:20:18
  • 4211

Mybatis接口在service注入失败的解决办法

Spring Dao的配置文件添加自动扫描mapper的接口。 其中如下代码为spring自扫描所有dao包并把其下的所有mybatis接口文件装配入容器....
  • lvchengbo
  • lvchengbo
  • 2017-01-12 20:52:06
  • 2044

如何在普通类中直接访问service层或dao层

1、最近遇到一个问题,如何在工具类中去访问dao层与service层的方法,因为可能本人底子比较薄弱,一开始未想到错误点在哪,后来debug才发现我的service或 dao 都是空的。    ...
  • HL_smile90
  • HL_smile90
  • 2017-08-02 09:07:55
  • 2931

java中dao层和service层的区别,为什么要用service?

读了下面的文章 让我豁然开朗我能不能理解 ssh中service就相当于与jsp+servlet+dao中的servlet???转文: 首先解释面上意思,service是业务层,dao是数据访问层。...
  • Ani521smile
  • Ani521smile
  • 2016-05-20 11:28:47
  • 19682

Java Web性能优化之一:减少DAO层的调用次数

关于java web中service多次调用dao层与数据库内部处理逻辑的性能对比
  • wlwlwlwl015
  • wlwlwlwl015
  • 2015-11-14 13:02:01
  • 1282

mybatis 逆向工程 自动生成controller service dao mapper model

  • 2017年08月14日 15:44
  • 24.42MB
  • 下载

DAO/Servlet/Service/Bean综合使用小例子

在这里不插入JSP的内容,仅仅只写出dao、servlet、service、bean的代码,用以记录典型的分层思想dao层在没有使用mybatis等框架的时候,完成注册、获取连接、执行sql并返回结果...
  • qq_28301007
  • qq_28301007
  • 2016-09-24 20:05:52
  • 3420
收藏助手
不良信息举报
您举报文章:关于Mybatis中foreach的用法以及与service中循环调用dao层中的差异
举报原因:
原因补充:

(最多只允许输入30个字)