项目用例
关于foreach 标签,有几个属性应该注意一下:
属性描述
collection 指定要遍历的集合,list类型的参数会特殊处理封装在map中,map的key就叫list
item 将当前遍历出的元素赋值给指定的变量
separator 每个元素之间的分隔符
open 遍历出所有结果拼接一个开始的字符
close 遍历出所有结果拼接一个结束的字符
index 索引。遍历list的时候是index就是索引,item就是当前值。遍历map的时候index表示的就是map的key,item就是map的值, #{变量名}就能取出变量的值也就是当前遍历出的元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 # 一、使用MyBatis对表执行UPDATE批处理——基于XML的实现 ## 1、定义mapper接口方法 ```java public interface UserMapper extends BaseDao<UserModel> { //Mybatis中进行批量更新1 public int updateBatch1(List<User>) throws Exception; //Mybatis中进行批量更新2 public int updateBatch2(List<User>) throws Exception; }
## 2、定义sql映射xml文件
以userMapper.xml文件的CUD内容为例,如下:
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 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace ="com.tre.mapper.userMapper" > <cache type ="org.mybatis.caches.ehcache.LoggingEhcache" /> <resultMap id ="BaseResultMap" type ="com.tre.model.SysLog" > <id column ="id" property ="id" /> <result column ="userid" property ="userid" /> <result column ="username" property ="username" /> <result column ="years" property ="years" /> </resultMap > <update id ="updateBatch1" parameterType ="java.util.List" > <foreach collection ="list" item ="item" index ="index" open ="" close ="" separator =";" > update users <set > name=${item.name} </set > where id = ${item.id} </foreach > </update > <update id ="updateBatch2" parameterType ="java.util.List" > update users set status= <foreach collection ="list" item ="item" index ="index" separator =" " open ="case ID" close ="end" > when #{item.id} then #{item.status} </foreach > where id in <foreach collection ="list" index ="index" item ="item" separator ="," open ="(" close =")" > #{item.id,jdbcType=BIGINT} </foreach > </update > </mapper >
# 二、使用MyBatis对表执行INSERT批处理——基于XML的实现
## 第一种:
1 INSERT INTO table (field1,field2,field3) VALUES ('a' ,"b" ,"c" ), ('a' ,"b" ,"c" ),('a' ,"b" ,"c" )
Mybatis通过foreach循环拼装了如上的sql语句。
### 1、定义对应的mapper接口
1 public void insertBatch (@Param("emps") List<User> emps) ;
### 2、定义sql映射xml文件
这里以批量插入数据为例:
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 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace ="com.tre.mapper.userMapper" > <cache type ="org.mybatis.caches.ehcache.LoggingEhcache" /> <resultMap id ="BaseResultMap" type ="com.tre.model.SysLog" > <id column ="id" property ="id" /> <result column ="userid" property ="userid" /> <result column ="username" property ="username" /> <result column ="years" property ="years" /> </resultMap > <insert id ="insertBatch" parameterType ="java.util.List" > INSERT INTO tb1_emplyee(userid,username,years) VALUES <foreach collection ="emps" item ="emp" separator ="," > (#{emp.userid},#{emp.username},#{emp.years}) </foreach > </insert > </mapper >
### 3,junit类测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Resource private UserMapper userMapper;@Test public void testInsertBatch () throws Exception { long start = System.currentTimeMillis(); List<User> list = new ArrayList <>(); User user; for (int i = 0 ; i < 10000 ; i++) { user = new User (); user.setUserid("test" + i); user.setUsername("name" + i); user.setYears(20 ); list.add(user); } userMapper.insertBatch(list); long end = System.currentTimeMillis(); System.out.println("---------------" + (start - end) + "---------------" ); }
**特别注意:**
mysql默认接受sql的大小是1048576(1M),即第三种方式若数据量超过1M会报如下异常:
1 2 3 4 5 (可通过调整MySQL安装目录下的my.ini文件中[mysqld]段的"max_allowed_packet = 1M") nested exception is com.mysql.jdbc.PacketTooBigException: Packet for query is too large (5677854 > 1048576). You can change this value on the server by setting the max_allowed_packet' variable.
## 第二种:
mybatis BATCH模式插入
### 1、定义对应的mapper接口
1 2 3 4 5 6 7 8 9 public void insert (@Param("user") User user) ;```java ### 2 、定义sql映射xml文件 ```xml <insert id="insert" > INSERT INTO t_user (id, name, del_flag) VALUES(#{id}, #{name}, #{delFlag}) </insert>
### 3,junit类测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Test public void testInsertBatch2 () throws Exception { long start = System.currentTimeMillis(); User user; SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false ); UserDao mapper = sqlSession.getMapper(UserDao.class); for (int i = 0 ; i < 500 ; i++) { user = new User (); user.setId("test" + i); user.setName("name" + i); user.setDelFlag("0" ); mapper.insert(user); } sqlSession.commit(); long end = System.currentTimeMillis(); System.out.println("---------------" + (start - end) + "---------------" ); }
## 注意:
第一种方式
我测试了1w条数据的时候差不多需要一秒多时间,可是当我改成10w条的时候,直接ka着不会动了。这种方式是把所有数据拼成一条sql传递给数据库。
第二种方式
在测试1w条的时候虽然看起来比拼接sql慢一点,但在插入10w条的时候不会卡死,差不多就是插入1w条的10倍。数据量较大时推荐使用mybatis提供的ExcecutorType.BATCH。
# 三、使用MyBatis对表执行DELETE批处理——基于XML的实现
当collection=”array“时,表名参数为数组;
当collection=”list“时,表名参数为集合.
## 1、定义对应的mapper接口
public void deleteBatch(int[] arr);
## 2、定义sql映射xml文件
这里以批量插入数据为例:
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 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace ="com.tre.mapper.userMapper" > <cache type ="org.mybatis.caches.ehcache.LoggingEhcache" /> <resultMap id ="BaseResultMap" type ="com.tre.model.SysLog" > <id column ="id" property ="id" /> <result column ="userid" property ="userid" /> <result column ="username" property ="username" /> <result column ="years" property ="years" /> </resultMap > <delete id ="deleteBatch" parameterType ="int[]" > delete from emp where empno in <foreach collection ="array" item ="arr" index ="no" open ="(" separator ="," close =")" > #{arr} </foreach > </delete > </mapper >
## 3,junit类测试
1 2 3 4 5 6 7 8 9 10 11 12 @Resource private UserMapper userMapper;@Test public void testInsertBatch () throws Exception { long start = System.currentTimeMillis(); System.out.println("----------批量删除----------" ); int [] arr = { 7791 , 7792 }; userMapper.deleteBatch(arr); long end = System.currentTimeMillis(); System.out.println("---------------" + (start - end) + "---------------" ); }