MyBatis and MyBatis-Plus Batch Insert Techniques with Performance Comparison
This article presents five common batch‑insert approaches for MyBatis and MyBatis‑Plus—including a for‑loop, manual batch commit, collection‑based batch, saveBatch, and InsertBatchSomeColumn—provides complete code examples, configuration steps, and measured execution times to help Java backend developers choose the most efficient method.
Introduction
The author lists five frequently used batch‑insert methods for MyBatis and MyBatis‑Plus, summarizes their usage, and shares performance results.
Preparation
1. Add Maven dependencies for MySQL, MyBatis‑Spring‑Boot‑Starter, MyBatis‑Plus, and Lombok.
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- MyBatis dependency -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<!-- MyBatis‑Plus dependency -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>2. Configure application.yml with datasource and MyBatis mapper locations.
server:
port: 8080
spring:
datasource:
username: mysql用户名
password: mysql密码
url: jdbc:mysql://localhost:3306/数据库名字?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:mapping/*.xml3. Define a common User entity.
@Data
public class User {
private int id;
private String username;
private String password;
}1. For‑loop Batch Insert (MyBatis)
Service class iterates 10,000 times, creates a User, and calls userMapper.insertUsers(user). Mapper interface defines Integer insertUsers(User user). XML mapper contains a simple INSERT statement.
@Service
public class UserService {
@Resource
private UserMapper userMapper;
public void InsertUsers() {
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
User user = new User();
user.setUsername("name" + i);
user.setPassword("password" + i);
userMapper.insertUsers(user);
}
long end = System.currentTimeMillis();
System.out.println("一万条数据总耗时:" + (end - start) + "ms");
}
}Result: ~26,348 ms.
2. Manual Batch Commit (MyBatis)
Uses SqlSessionTemplate with ExecutorType.BATCH and disables auto‑commit. After the loop, sqlSession.commit() is called.
@Service
public class UserService {
@Resource
private UserMapper userMapper;
@Resource
private SqlSessionTemplate sqlSessionTemplate;
public void InsertUsers() {
SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory()
.openSession(ExecutorType.BATCH, false);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
User user = new User();
user.setUsername("name" + i);
user.setPassword("password" + i);
mapper.insertUsers(user);
}
sqlSession.commit();
long end = System.currentTimeMillis();
System.out.println("一万条数据总耗时:" + (end - start) + "ms");
}
}Result: ~24,516 ms.
3. Collection‑Based Batch Insert (MyBatis – Recommended)
Collects all User objects into a List and passes it to a single mapper method using MyBatis foreach.
@Service
public class UserService {
@Resource
private UserMapper userMapper;
public void InsertUsers() {
long start = System.currentTimeMillis();
List<User> userList = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
User user = new User();
user.setUsername("name" + i);
user.setPassword("password" + i);
userList.add(user);
}
userMapper.insertUsers(userList);
long end = System.currentTimeMillis();
System.out.println("一万条数据总耗时:" + (end - start) + "ms");
}
}Mapper XML uses <foreach> to generate multiple VALUES rows.
<insert id="insertUsers">
INSERT INTO user (username, password)
VALUES
<foreach collection="userList" item="user" separator=",">
(#{user.username}, #{user.password})
</foreach>
</insert>Result: ~521 ms.
4. SaveBatch (MyBatis‑Plus)
Extends ServiceImpl and calls saveBatch(userList) provided by MyBatis‑Plus.
@Service
public class UserService extends ServiceImpl<UserMapper, User> implements IService<User> {
public void InsertUsers() {
long start = System.currentTimeMillis();
List<User> userList = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
User user = new User();
user.setUsername("name" + i);
user.setPassword("password" + i);
userList.add(user);
}
saveBatch(userList);
long end = System.currentTimeMillis();
System.out.println("一万条数据总耗时:" + (end - start) + "ms");
}
}Result: ~24,674 ms (due to default batch size).
5. InsertBatchSomeColumn (MyBatis‑Plus – Recommended)
Creates a custom SQL injector to add insertBatchSomeColumn, which inserts only non‑null columns.
public class EasySqlInjector extends DefaultSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
methodList.add(new InsertBatchSomeColumn(i -> i.getFieldFill() != FieldFill.UPDATE));
return methodList;
}
}Configuration bean registers the injector, and the mapper extends a custom EasyBaseMapper that declares Integer insertBatchSomeColumn(Collection<T> entityList).
@Configuration
public class MybatisPlusConfig {
@Bean
public EasySqlInjector sqlInjector() {
return new EasySqlInjector();
}
}Service uses userMapper.insertBatchSomeColumn(userList).
public void InsertUsers() {
long start = System.currentTimeMillis();
List<User> userList = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
User user = new User();
user.setUsername("name" + i);
user.setPassword("password" + i);
userList.add(user);
}
userMapper.insertBatchSomeColumn(userList);
long end = System.currentTimeMillis();
System.out.println("一万条数据总耗时:" + (end - start) + "ms");
}Result: ~575 ms.
Conclusion
The collection‑based batch insert (method 3) and the custom InsertBatchSomeColumn method (method 5) deliver the best performance, reducing the insertion time of 10,000 records to under a second, while the simple for‑loop approach is orders of magnitude slower.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
