Backend Development 14 min read

Optimizing Batch Insert Performance with MyBatis-Plus: Configuration, Custom Methods, and Multithreading

This article explains why MyBatis-Plus's saveBatch() can be slow for large data sets, shows how enabling rewriteBatchedStatements in the JDBC URL dramatically speeds up inserts, and demonstrates custom batch insert/update methods and multithreaded execution to further improve performance, complete with code examples and test results.

Java Architect Essentials
Java Architect Essentials
Java Architect Essentials
Optimizing Batch Insert Performance with MyBatis-Plus: Configuration, Custom Methods, and Multithreading

Background

When synchronizing tens of thousands of base records from one system to another, using MyBatis-Plus's saveBatch() method without proper JDBC configuration can take many minutes per run.

The main cause is the missing rewriteBatchedStatements=true parameter in the MySQL connection URL.

Enabling Batch Rewrite

Add the following to the JDBC URL:

jdbc:mysql://
host
/
database
?useUnicode=true&characterEncoding=UTF8&allowMultiQueries=true&rewriteBatchedStatements=true

After enabling this flag, inserting 10,000 rows takes only a few hundred milliseconds.

Optimization Methods

2.1 MyBatis-Plus Built‑in saveBatch()

Entity definition:

@Data
@TableName("test_user")
public class TestUser implements Serializable {
    private String id;
    private String name;
    private String managerId;
    private String salary;
    private String age;
    private String departId;
    private String remark;
    private String province;
}

Mapper:

public interface TestUserMapper extends BaseMapper
{}

Service interface:

public interface ITestUserService extends IService
{}

Unit‑test inserting 200,000 rows with saveBatch() takes about 10 seconds.

2.2 Custom Batch Insert/Update

Create a generic RootMapper extending BaseMapper with custom methods:

public interface RootMapper
extends BaseMapper
{
    int insertBatch(@Param("list") Collection
batchList);
    int updateBatch(@Param("list") Collection
batchList);
}

Implement custom SQL injection classes:

public class InsertBatchColumn extends AbstractMethod {
    // builds INSERT ... VALUES script using MyBatis foreach
}

public class UpdateBatchColumn extends AbstractMethod {
    // builds UPDATE ... WHERE script using MyBatis foreach
}

Register them via a custom injector:

@Configuration
public class MybatiesPlusConfig {
    @Bean
    public MysqlInjector sqlInjector() {
        return new MysqlInjector();
    }
}

Now the mapper can call insertBatch() and updateBatch() directly.

2.3 Multithreaded Updates with saveBatch()

Using a fixed thread pool of 5 threads, each thread processes a batch of 5,000 records and calls userService.saveBatch(batchList) . Total time drops to ~3 seconds.

2.4 Multithreaded Custom Batch Insert

Similar thread pool, but each thread invokes testUserMapper.insertBatch(filteredList) . Execution time is about 2 seconds.

Summary

Setting rewriteBatchedStatements=true makes the built‑in batch insert fast enough for most cases (≈4 seconds for 200k rows). When further speed is needed, multithreading reduces the time to ~1 second, and custom batch methods provide comparable performance while offering more control.

Javaperformance optimizationdatabasemultithreadingMyBatis-Plusbatch insert
Java Architect Essentials
Written by

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.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.