背景:
项目要做国产化改造,数据库由mysql切换为达梦数据库,过程中遇到一个问题,批量插入数据后,使用数据自增主键的问题,该逻辑在mysql数据库是能够正常执行的,插入能正常获取数据自增主键,但是在DM数据库中就不能正常执行,数据主键不能获取到。返回自增主键的实现方式使用mybatis的useGeneratedKeys,在mapper.xml文件的对应statement上设置useGeneratedKeys为true。
本文对orm框架与数据库在哪种使用方式下会返回主键进行了探究。
mybatis-plus框架版本及数据库版本:
mybatis-plus:使用spring-boot-starter引入,版本为3.5.6
MySQL: 大版本为8
达梦数据库: 大版本为8
代码:
service:
java
复制代码
@Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService { }
mapper:
java
复制代码
@Mapper public interface UserMapper extends BaseMapper<User> { void insertBatch(@Param("users") List<User> users); }
xml:
xml
复制代码
<?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.belizer.mybatisplus.mapper.UserMapper"> <insert id="insertBatch" keyProperty="id" useGeneratedKeys="true"> insert into "user" (name, age) values <foreach collection="users" item="user" index="index" separator=","> (#{user.name}, #{user.age}) </foreach> </insert> </mapper>
测试代码:
xml
复制代码
@Autowired private UserMapper userMapper; @Autowired private UserService userService; @Test public void testInsert() { User user = new User(); user.setName("zhangsan"); user.setAge(18); user.setEmail("2233@bilibili.com"); userService.save(user); /** * 插入后,自动回填id,是默认行为 */ System.out.println(user); } @Test public void testInsertBatch() { List<User> userList = new ArrayList<>(); for (int i = 0; i < 5; i++) { User user = new User(); user.setName("zhangsan" + i); user.setAge(18 + i); user.setEmail("2233@bilibili.com" + i); userList.add(user); } userService.saveBatch(userList); /** * 插入后,自动回填id,是默认行为 */ System.out.println(userList); } /** * 使用自定义sql 达梦数据库并不能通过设置useGeneratedKeys为true来支持批量插入返回主键 */ @Test public void testInsertBatch2() { List<User> userList = new ArrayList<>(); for (int i = 0; i < 5; i++) { User user = new User(); user.setName("zhangsan" + i); user.setAge(18 + i); user.setEmail("2233@bilibili.com" + i); userList.add(user); } userMapper.insertBatch(userList); /** * 插入后,自动回填id,是默认行为 */ System.out.println(userList); }
测试结果:
达梦数据库下的执行情况:
testInsert:
xml
复制代码
User(id=18, name=zhangsan, age=18, email=2233@bilibili.com)
testInsertBatch:
xml
复制代码
[User(id=19, name=zhangsan0, age=18, email=2233@bilibili.com0), User(id=20, name=zhangsan1, age=19, email=2233@bilibili.com1), User(id=21, name=zhangsan2, age=20, email=2233@bilibili.com2), User(id=22, name=zhangsan3, age=21, email=2233@bilibili.com3), User(id=23, name=zhangsan4, age=22, email=2233@bilibili.com4)]
testInsertBatch2:
xml
复制代码
[User(id=null, name=zhangsan0, age=18, email=2233@bilibili.com0), User(id=null, name=zhangsan1, age=19, email=2233@bilibili.com1), User(id=null, name=zhangsan2, age=20, email=2233@bilibili.com2), User(id=null, name=zhangsan3, age=21, email=2233@bilibili.com3), User(id=null, name=zhangsan4, age=22, email=2233@bilibili.com4)]
可以看出使用自定义sql,达梦数据库并不能通过设置useGeneratedKeys为true来支持批量插入返回自增主键,但是使用mybatis-plus实现的saveBatch方法是可以返回自增主键的。
MySQL数据库下的执行情况:
testInsert:
xml
复制代码
User(id=18, name=zhangsan, age=18, email=2233@bilibili.com)
testInsertBatch:
xml
复制代码
[User(id=19, name=zhangsan0, age=18, email=2233@bilibili.com0), User(id=20, name=zhangsan1, age=19, email=2233@bilibili.com1), User(id=21, name=zhangsan2, age=20, email=2233@bilibili.com2), User(id=22, name=zhangsan3, age=21, email=2233@bilibili.com3), User(id=23, name=zhangsan4, age=22, email=2233@bilibili.com4)]
testInsertBatch2:
xml
复制代码
[User(id=1781194760655835141, name=zhangsan0, age=18, email=2233@bilibili.com0), User(id=1781194760655835142, name=zhangsan1, age=19, email=2233@bilibili.com1), User(id=1781194760655835143, name=zhangsan2, age=20, email=2233@bilibili.com2), User(id=1781194760655835144, name=zhangsan3, age=21, email=2233@bilibili.com3), User(id=1781194760655835145, name=zhangsan4, age=22, email=2233@bilibili.com4)]
可以看出使用自定义sql,MySQL数据库能通过设置useGeneratedKeys为true来支持批量插入返回自增主键。
总结:
因为目前项目暂不需要考虑性能问题,可以使用mybatis-plus实现的saveBatch方法。