【Java】MyBatis 批量插入数据,以及性能测试
测试环境
Java 1.8 ,spring boot 2.6.4具体依赖如下
org.springframework.boot
spring-boot-starter-web
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.2.2
com.baomidou
mybatis-plus-boot-starter
3.5.0
mysql
mysql-connector-java
runtime
com.zaxxer
HikariCP
org.projectlombok
lombok
provided
org.springframework.boot
spring-boot-starter-test
test
Mapper.xml配置
insert into user
(name,password,createtime)
values
(#{item.name},#{item.password},#{item.createTime})
UserMapper.java
@Mapper
public interface UserMapper extends BaseMapper {
boolean saveBatchCustom(List list);
}
UserService.java
@Service
public class UserService extends ServiceImpl {
@Autowired
private UserMapper userMapper;
@Autowired
private JdbcTemplate jdbcTemplate;
@Transactional
public boolean saveBatchCustom(List list) {
return userMapper.saveBatchCustom(list);
}
@Transactional
public void jdbcBatchInsert(List list, final int batchSize) {
String sql = "insert into user (name,password,createtime) values(?,?,?)";
jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
UserPO userPO = list.get(i);
ps.setString(1, userPO.getName());
ps.setString(2, userPO.getPassword());
ps.setDate(3, new Date(userPO.getCreateTime().getTime()));
}
@Override
public int getBatchSize() {
return batchSize < 1 ? 1000 : batchSize;
}
});
}
}
测试类
@SpringBootTest
public class BatchInsertDataTest {
private Logger logger = LoggerFactory.getLogger(getClass());
private static final int MAXCOUNT = 10000;
@Autowired
private UserMapper userMapper;
@Autowired
private UserService userService;
@BeforeEach
public void atest1() {
Wrapper query = new QueryWrapper();
userMapper.delete(query);
logger.info("清空数据表");
}
@Test
public void mybatisForeach() {
StopWatch sw = new StopWatch("testBatchInsert2");
sw.start();
List list = new ArrayList<>();
UserPO user = null;
for (int i = 0; i < MAXCOUNT; i++) {
user = new UserPO();
user.setName("test" + i);
user.setPassword("p" + i);
list.add(user);
}
userService.saveBatchCustom(list);
sw.stop();
logger.info("saveBatchCustom:{}", sw.getTotalTimeMillis());
}
@Test
public void mybatisPlusBatchSave() {
StopWatch sw = new StopWatch("mybatisPlusBatchSave");
sw.start();
List list = new ArrayList<>();
UserPO user = null;
for (int i = 0; i < MAXCOUNT; i++) {
user = new UserPO();
user.setName("test" + i);
user.setPassword("p" + i);
list.add(user);
}
userService.saveBatch(list, 500);
sw.stop();
logger.info("mybatisPlusBatchSave:{}", sw.getTotalTimeMillis());
}
@Test
public void jdbcBatchSave() {
StopWatch sw = new StopWatch("jdbcBatchSave");
sw.start();
List list = new ArrayList<>();
UserPO user = null;
for (int i = 0; i < MAXCOUNT; i++) {
user = new UserPO();
user.setName("test" + i);
user.setPassword("p" + i);
user.setCreateTime(new Date());
list.add(user);
}
userService.jdbcBatchInsert(list, 500);
sw.stop();
logger.info("jdbcBatchSave:{}", sw.getTotalTimeMillis());
}
}
测试结果
在个人电脑上测试了一个大体范围。具体可能因环境而异,不会有太大差距
- 数据量大于1000
jdbcBatchSave > mybatisPlusBatchSave >mybatisForeach并随着数据量越大差距越大。 - 小于1000大于300
jdbcBatchSave > mybatisPlusBatchSave >mybatisForeach 之间性能差距在缩小,mybatisPlusBatchSave与mybatisForeach每次测试数据不固定, - 小于 300
推荐使用mybatisPlusBatchSave,