Mybatis3 批量执行操作
最近碰到几道Mybatis3的面试题,记录下。
1.Mybatis3 怎样执行批量插入?
使用Mybatis3中的<foreach>标签动态拼接需要插入的记录行数据。
基本语法复习,MySQL批量插入SQL如下:
INSERT INTO `user`(user_name, age, created_by, updated_by)
VALUES
('chen', 2, 'derek', 'derek'),
('chen', 2, 'derek', 'derek')
插入多态语句时,在values后用括号把要插入的数据包围,同时用逗号分隔每条记录。
还是使用user表来实践下。
CREATE TABLE `user` ( `USER_ID` int NOT NULL AUTO_INCREMENT, `USER_NAME` varchar(100) NOT NULL COMMENT '用户姓名', `AGE` int NOT NULL COMMENT '年龄', `CREATED_TIME` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `CREATED_BY` varchar(100) NOT NULL DEFAULT 'UNKNOWN', `UPDATED_TIME` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `UPDATED_BY` varchar(100) NOT NULL DEFAULT 'UNKNOWN', PRIMARY KEY (`USER_ID`) ) ENGINE=InnoDB AUTO_INCREMENT=345 DEFAULT CHARSET=utf8mb3
UserMapper.java接口定义如下:
public class UserMapper {
int batchInsertUsers(@Param("users") List<User> users);
}
Mybatis3 批量插入时,需要注意插入的最后一个逗号的清除,所以使用<trim>标签来处理比较好。
User Mapper.xml定义如下:
<insert id="batchInsertUsers" parameterType="list">
INSERT INTO `user`(user_name, age, created_by, updated_by)
<trim prefix="VALUES" suffixOverrides=",">
<foreach collection="users" index="index" item="user" separator=",">
(
#{user.userName, jdbcType=VARCHAR},
#{user.age, jdbcType=INTEGER},
#{user.createdBy, jdbcType=VARCHAR},
#{user.updatedBy, jdbcType=VARCHAR}
)
</foreach>
</trim>
</insert>
测试代码如下:
package com.derek.mapper;
import com.derek.model.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class UserMapperTest {
private static SqlSessionFactory sqlSessionFactory;
private static SqlSession sqlSession;
private static UserMapper userMapper;
@BeforeAll
public static void setUp() throws IOException {
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
sqlSessionFactory = new org.apache.ibatis.session.SqlSessionFactoryBuilder().build(reader);
sqlSession = sqlSessionFactory.openSession();
userMapper = sqlSession.getMapper(UserMapper.class);
}
@AfterAll
public static void tearDown() {
userMapper = null;
sqlSession.close();
}
@Test
public void testInsertBatch() {
List<User> users = new ArrayList<>();
for(int i=1; i<=10; i++) {
User user = new User();
user.setUserName("batch name-" + i);
user.setAge(i);
user.setCreatedBy("robot");
user.setCreatedTime(new Date());
user.setUpdatedBy("robot");
user.setUpdatedTime(new Date());
users.add(user);
}
userMapper.batchInsertUsers(users);
sqlSession.commit();
}
}
2.Mybatis3 怎样执行批量操作(插入/更新/删除)?
使用 ExecutorType.BATCH
模式
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
然后进行批量插入/更新/删除操作,再进行提交。
具体的示例如下:
1)插入100条user记录。
2)修改100条user记录。
3)删除100条user记录。
把上述300条操作做成一个batch执行。
@Test
public void testBatchOperation() {
try (SqlSession batchSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
UserMapper userMapper = batchSession.getMapper(UserMapper.class);
// insert 100 users
for(int i=1; i<=100; i++) {
User user = new User();
user.setUserName("batch name-" + i);
user.setAge(i);
user.setCreatedBy("robot");
user.setCreatedTime(new Date());
user.setUpdatedBy("robot");
user.setUpdatedTime(new Date());
userMapper.insert(user);
}
// update 100 users
UserExample userExample = new UserExample();
userExample.createCriteria().andUserNameLike("%batch name%");
User updatedUser = new User();
updatedUser.setUserName("updated name");
userMapper.updateByExampleSelective(updatedUser, userExample);
// delete 100 users
UserExample deleteExample = new UserExample();
deleteExample.createCriteria().andUserNameLike("updated name");
userMapper.deleteByExample(deleteExample);
// commit the batch
batchSession.commit();
}