MyBatis 通过 useGeneratedKeys="true" 和 keyProperty 指定字段,可在 INSERT 后自动回填数据库自增主键值到 Java 对象;需确保驱动支持、引擎正确、setter 规范且 SQL 无分号等干扰。

MyBatis 利用 useGeneratedKeys 和 keyProperty 可以在执行 INSERT 语句后,自动将数据库生成的自增主键值回填到 Java 对象的指定字段中,无需额外查询。
核心配置项说明
useGeneratedKeys:设为 true 表示启用 JDBC 的 getGeneratedKeys() 获取自增主键;
keyProperty:指定 Java 对象中接收主键值的属性名(支持嵌套,如 user.id);
keyColumn(可选):明确指定数据库表中对应的主键列名,尤其在多主键或列名与属性名不一致时推荐使用。
XML 映射文件写法
在 <insert> 标签中配置:
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
INSERT INTO user (username, email) VALUES (#{username}, #{email})
</insert>
假设 User 类有 id、username、email 字段,插入后 user.getId() 就能拿到数据库分配的自增 ID。
常见注意事项
- 数据库驱动需支持
getGeneratedKeys()(主流 MySQL、PostgreSQL、SQL Server 均支持) - MySQL 中必须使用
InnoDB引擎且主键为AUTO_INCREMENT -
keyProperty必须与 Java 对象的 setter 方法名匹配(遵循驼峰规则,如userId对应setUserId()) - 若使用
@Options注解方式,写法为:@Options(useGeneratedKeys = true, keyProperty = "id") - 批量插入时,每个对象的主键都会被分别回填(MyBatis 3.4+ 支持批量 + 自增主键回填)
为什么有时回填失败?
典型原因包括:
— SQL 语句末尾有多余分号(如 VALUES (...);),导致 JDBC 无法正确识别生成键;
— 实体类字段没有 public setter 或 setter 名称不规范;
— 使用了 SELECT LAST_INSERT_ID() 等手动方式,干扰了 MyBatis 的自动机制;
— 数据库连接 URL 缺少必要参数,例如 MySQL 需确保 useServerPrepStmts=false 或兼容模式开启。


















