数据库--MyBatis的(insert,update,delete)三种批量操作

转自:http://blog.csdn.net/starywx/article/details/23268465

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
前段时间由于项目赶期没顾上开发过程中的性能问题,现对部分代码进行优化的过程中发现在数据量大的情况下对数据的操作反应似乎有些慢,就想到对数据库DML操作的时候进行批量操作。说道这里也想到自己在一次面试的时候别问道过批量操作数据的问题。
现对运用说明记录如下:
批量插入insert
方法一:
<insert id="insertbatch" parameterType="java.util.List">
  <selectKey keyProperty="id" order="AFTER"
  resultType="int">
  SELECT LAST_INSERT_ID()
  </selectKey>
   INSERT INTO  sourcedoc (
sdate, sweek,
      roomno, daysched, nightsched,
      adminsched, vacationsched, programdept,
      programname
)values
<foreach collection="list" item="item" index="index" separator=",">
(
#{item.sdate},#{item.sweek},#{item.roomno},
#{item.daysched},#{item.nightsched},#{item.adminsched},
#{item.vacationsched},#{item.programdept},#{item.programname}
        )
</foreach>
</insert>
方法二:
<insert id="batchInsert" parameterType="ArrayList">
insert into table1(sdate,sweek,roomno,daysched,nightsched,adminsched,vacationsched,programdept,programname)
<foreach collection="list" item="item" index="index" separator="union all">
select #{item.sdate,jdbcType=VARCHAR},
#{item.sweek,jdbcType=VARCHAR},
#{item.roomno,jdbcType=VARCHAR},
#{item.nightsched,jdbcType=VARCHAR},
#{item.adminsched,jdbcType=VARCHAR},
#{item.vacationsched,jdbcType=VARCHAR},
#{item.programdept,jdbcType=VARCHAR},0,0,
#{item.programname,jdbcType=VARCHAR} from dual
</foreach>
</insert>
  
可以考虑用union all来实现批量插入。
例如:
insert into XX_TABLE(XX,XX,XX)select 'xx','xx','xx' union all select 'xx','xx','xx' union all select 'xx','xx','xx' ...
先拼装好语句再动态传入insert into XX_TABLE(XX,XX,XX)后面部分
  
批量删除(delete)
<!-- 通过主键集合批量删除记录 -->
<delete id="batchRemoveUserByPks" parameterType="java.util.List">
DELETE FROM LD_USER WHERE ID in 
<foreach item="item" index="index" collection="list" open="(" separator="," close=")">
#{item}
</foreach>
</delete>
  
批量修改(update)
 <update id="updateOrders" parameterType="java.util.List">
 update orders set state = '0' where no in
 <foreach collection="list" item="nos" open="(" separator="," close=")">
  #{nos}
 </foreach>
 </update>
  
MyBatis中in子句  in 参数 使用方法
1.只有一个参数
参数的类型要声明为List或Array
Sql配置如下:
<select id="selectProduct" resultMap="Map">
SELECT * FROM PRODUCT
WHERE PRODUCTNO IN
      <foreach item="productNo" index="index" collection="参数的类型List或array">
                   #{productNo}
     </foreach>
</select>
  
2.多个参数
首先要将多个参数写入同一个map,将map作为一个参数传入mapper
Sql配置如下:
<select id="selectSoucedoc" resultMap="Map">
SELECT *
FROM PRODUCT
WHERE PRODUCTNO IN
     <foreach item="id" index="index" collection="map中集合参数的名称">
            #{id}
    </foreach>
</select>
 
 
批量数据操作的体会
 MyBatis的前身就是著名的Ibatis,不知何故脱离了Apache改名为MyBatis。
 MyBatis所说是轻量级的ORM框架,在网上看过一个测试报告,感觉相比于Hibernate来说,优势并不明显。
下面说一下比较有趣的现象,根据MyBatis的官方文档,在获得sqlSession时,它有为批量更新而专门准备的:
 
session = sessionFactory.openSession();//用于普通update
session = sessionFactory.openSession(ExecutorType.BATCH, true);//用于批量update
 
 一般来说,对MYSQL数据库批量操作时速度取决于,是为每一个处理分别建立一个连接,还是为这一批处理一共建立一个连接。按MyBatis的手册说明,选择ExecutorType.BATCH意味着,获得的sqlSession会批量执行所有更新语句。不过我测试了一下,批量插入1000条数据,发觉ExecutorType.BATCH方式的效率居然比普通的方式差很多。我测试用的Mapper中的insert配置如下,再用for循环插入1000条记录:
 
<insert id="insert" parameterType="sdc.mybatis.test.Student">
insert into student (id, name, sex,
address, telephone, t_id
)
values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},
#{sex,jdbcType=VARCHAR},
#{address,jdbcType=VARCHAR}, #{telephone,jdbcType=VARCHAR}, #{tId,jdbcType=INTEGER}
)
</insert>
 
   
 
关于数据库批量插入时sql语句级的优化,我特意测试了两种方式,在StudentMapper中配置了两种insert模式。第一种对应insert value1,insert value2,,,,;第二种对应insert values (value1, value2,....)。发现后者果然比前者快很多啊。下面是两种insert模式,及测试结果对应图:
  
<!-- 批量 ,传入一个长度为1000的list -->
insert into student ( <include refid="Base_Column_List"/> )
values
<foreach collection="list" item="item" index="index" separator=",">
(null,#{item.name},#{item.sex},#{item.address},#{item.telephone},#{item.tId})
</foreach>
</insert>
<!-- 在外部for循环调用一千次 -->
<insert id="insert" parameterType="sdc.mybatis.test.Student">
insert into student (id, name, sex,
address, telephone, t_id
)
values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},
#{sex,jdbcType=VARCHAR},
#{address,jdbcType=VARCHAR}, #{telephone,jdbcType=VARCHAR}, #{tId,jdbcType=INTEGER}
)
</insert>

  

posted @   xh_Blog  阅读(1922)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示