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);
        }
    }
}

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐