mybatis plus新增(insert)数据获取主键id问题
·
0 前言
执行insert时,往往需拿到新插入数据的主键id,以做下一步操作。
User user = new User();
user.setName(request.getName());
int index = userMapper.insert(user);
这insert之后返回的index是你增加的数据列数,而非主键id。
1 解决方案
获取主键id,只需在insert之后直接get该对象的主键id:
User user = new User();
user.setName(request.getName());
userMapper.insert(user);
Long id = user.getId();
2 原理解析
基于 MyBatis-Plus 默认行为,这背后依赖 MyBatis-Plus 的两个核心机制:
2.1 默认主键生成策略
若实体类主键字段有 @TableId(type = IdType.AUTO) 或使用默认的 ASSIGN_ID(基于雪花算法),MP 会在插入前生成ID。
2.2 自动回填机制
MP 在执行 insert 后,会自动把生成的主键值设置回实体对象的对应属性(通常是 id)。所以插入完成后,之前传入的 bankCard 对象内部状态已被更新。
主键生成器入口 - KeyGenerator
public interface KeyGenerator {
void processBefore(Executor executor, MappedStatement ms, Statement stmt, Object parameter);
// 在插入执行后回填主键
void processAfter(Executor executor, MappedStatement ms, Statement stmt, Object parameter);
}
核心回填逻辑 - MybatisParameterHandler
@Override
public void setParameters(PreparedStatement ps) throws SQLException {
// 获取主键生成器
KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
if (keyGenerator != null) {
keyGenerator.processBefore(executor, mappedStatement, ps, parameterObject);
}
// 执行 SQL
ps.execute();
if (keyGenerator != null) {
// 在执行后回填主键 ← 重点!
keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
}
}
JDBC 自增主键获取 - Jdbc3KeyGenerator
public class Jdbc3KeyGenerator implements KeyGenerator {
@Override
public void processAfter(Executor executor, MappedStatement ms,
Statement stmt, Object parameter) {
// 通过 JDBC 获取自增主键
ResultSet rs = stmt.getGeneratedKeys();
final Configuration configuration = ms.getConfiguration();
final TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
// 将主键值设置回实体对象
MetaObject metaObject = configuration.newMetaObject(parameter);
if (rs.next()) {
Object value = rs.getObject(1);
// 关键:通过反射设置实体的 id 字段
metaObject.setValue("id", value);
}
}
}

更多推荐

所有评论(0)