mybatis批量插入能回填自增主键,需满足:usegeneratedkeys="true"和keyproperty="id"必须配置在标签内;数据库为innodb且主键auto_increment;jdbc url禁用rewritebatchedstatements=true;实体有规范setter;sql末尾无分号。

MyBatis 批量插入时能回填自增主键,但必须满足几个关键条件,否则看似配置了却拿不到 ID —— 常见现象是所有对象的主键仍是 0 或 null。
useGeneratedKeys 必须写在 标签上
不能放在全局配置或
<insert id="insertBatch" usegeneratedkeys="true" keyproperty="id"></insert>- SQL 写法示例:
INSERT INTO user(name) VALUES <foreach>...</foreach> - keyProperty 指向 Java 对象的属性名(如
id),不是数据库字段名,也不是 getter 方法名
数据库和驱动要支持批量获取生成键
MySQL 5.7+ 和 8.0 默认支持,但有个隐藏开关会影响行为:
- JDBC URL 中若开启
rewriteBatchedStatements=true,驱动会合并多条 INSERT 为一条语句,导致getGeneratedKeys()只返回第一个 ID 或失败 - 解决办法:设为
false,或干脆不配(默认是 false) - 确认 MySQL 表引擎是 InnoDB,主键列带
AUTO_INCREMENT
Java 实体和 SQL 要匹配规范
回填失败往往出在细节上:
- 实体类字段要有 public setter,比如
private Long id;→ 必须有setId(Long) - Lombok 的
@Data生成的 setter 名,就是字段驼峰命名(userId→setUserId()),keyProperty 就写"userId" - 不支持嵌套属性,
keyProperty="address.id"会被忽略,不报错也不赋值 - SQL 末尾不能有多余分号,例如
VALUES (#{name});会导致 JDBC 无法识别生成键
MyBatis-Plus 用户更简单
不用手写 XML,直接在实体主键字段加注解:
-
@TableId(type = IdType.AUTO),插入后调用user.getId()即可 - 批量用
saveBatch(list),每个对象的 ID 都会被自动回填 - 全局配置也可统一设
id-type: auto,适合新项目起步











