使用mybatis注解@Options实现添加记录时返回主键值


官网:http://www.mybatis.org/mybatis-3/index.html

在使用mybatis作为ORM框架时,我通常更喜欢使用注解而非xml配置文件的方式。
业务场景:添加记录之后需要返回自己自增长的主键字段值。
通常,我们会将DAO层写成如下代码(以添加员工Staff为例):

public interface StaffDAO {
    @InsertProvider(type=StaffProvider.class, method="buildSinleStaff")
    @Options(useGeneratedKeys=true, keyProperty="staff_id", keyColumn="staff_id")
    public int addStaff(Staff staff);
}

显然,希望在执行addStaff()后返回新添加的员工记录的主键字段值,在这里为staff_id(staff_id为主键字段,且为自增类型)。
但是!!!经过多次验证,依然发现,返回值始终为:1!
跟踪mybatis源码发现,返回值其实是添加的记录数,而不是新加记录的主键字段值,所以永远为1。

mybatis添加记录时序图:

查看org.apache.ibatis.executor.statement.PreparedStatementHandler源码实现:

@Override
public int update(Statement statement) throws SQLException {
    PreparedStatement ps = (PreparedStatement) statement;
    ps.execute();
    int rows = ps.getUpdateCount();
    Object parameterObject = boundSql.getParameterObject();
    KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
    keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
    return rows;
}

显然,返回值是受影响的记录数量,即:添加的记录数。

那么如何才能取得新添加记录的主键字段值呢?继续跟踪源码(org.apache.ibatis.executor.statement.PreparedStatementHandler):

@Override
public int update(Statement statement) throws SQLException {
    PreparedStatement ps = (PreparedStatement) statement;
    ps.execute();
    int rows = ps.getUpdateCount();
    Object parameterObject = boundSql.getParameterObject();
    KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
    keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
    return rows;
}

显然,在执行插入记录操作之后,还执行了如下操作:

Object parameterObject = boundSql.getParameterObject();
KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);

在org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator中实现对主键字段的处理:

private void populateKeys(ResultSet rs, MetaObject metaParam, String[] keyProperties, TypeHandler<?>[] typeHandlers) throws SQLException {
    for (int i = 0; i < keyProperties.length; i++) {
        TypeHandler<?> th = typeHandlers[i];
        if (th != null) {
            Object value = th.getResult(rs, i + 1);
            metaParam.setValue(keyProperties[i], value);
        }
    }
}

恍然大悟!
在使用mybatis注解@Options(useGeneratedKeys=true)获取新添加记录的自增长主键字段值时,需要在执行添加操作之后,直接访问对象的主键字段属性即可取得对应值
回归到业务代码:

staffService.addStaff(staff);
long staffId = staff.getStaff_id(); // 执行添加操作之后获取对象主键字段值

最后需要说明:在mybatis中使用注解实现添加记录时,可以使用@Insert或者@InsertProvider 2个注解,都可以使用@Options注解获取新添加记录的自增长主键字段值。

【参考】
http://isilic.iteye.com/blog/1810782 Mybatis使用:Sql Annotation

时间: 2024-10-11 13:59:46

使用mybatis注解@Options实现添加记录时返回主键值的相关文章

mybatis添加记录时返回主键id

参考:https://www.cnblogs.com/nuccch/p/7687281.html 场景 有些时候我们在添加记录成功后希望能直接获取到该记录的主键id值,而不需要再执行一次查询操作.在使用mybatis作为ORM组件时,可以很方便地达到这个目的.鉴于mybatis目前已经支持xml配置和注解2种方式,所以分别给予详细介绍. 数据表设计: drop table if exists `test`; create table `test` ( `id` bigint(20) NOT NU

Mybatis在insert时返回主键id

需要注意的地方:1.添加记录能够返回主键的关键点在于需要在标签中添加以下三个属性.useGeneratedKeys:必须设置为true,否则无法获取到主键id.keyProperty:设置为POJO对象的主键id属性名称.keyColumn:设置为数据库记录的主键id字段名称2.新添加主键id并不是在执行添加操作时直接返回的,而是在执行添加操作之后将新添加记录的主键id字段设置为POJO对象的主键id属性调用时: roomCheckInfoMapper.insertSelective(roomC

Mybatis 插入数据后返回主键值

Oracle中获取刚刚插入记录的主键值: <insert id="insertSelective" parameterType="com.jxxx.p2pp.model.UUserInfo">     <selectKey resultType="java.math.BigDecimal" order="BEFORE" keyProperty="id">    SELECT U_US

MyBatis在Oracle中插入数据并返回主键的问题解决

引言:  在MyBatis中,希望在Oracle中插入数据之时,同时返回主键值,而非插入的条数... 环境:MyBatis 3.2 , Oracle, Spring 3.2   SQL Snippet in XML Configuration: <insert id="insertSelective" parameterType="com.jxxx.p2pp.model.UUserInfo"> <selectKey resultType="

是数据库设置主键自增的时候添加也可以自定义主键值

SET IDENTITY_INSERT  dbo.PDAUserInfo ON //开启当前表的可复制功能,仅在当前绘画中有效 insert into dbo.PDAUserInfo(ID,UserName) values(43,'asdf') SET IDENTITY_INSERT  dbo.PDAUserInfo OFF    //关闭当前表的可复制功能,仅在当前绘画中有效 insert into dbo.PDAUserInfo(UserName) values('asdf') 是数据库设置

如何使用myBatis在数据库中插入数据并返回主键

在MyBatis中,希望在Oracle中插入数据的同时返回主键值,而非插入的条数. ① oracle使用 selectKey. U_USER_INFO_SEQ 是在数据库中定义好的这张表关联的序列sequence, Nextval是获取自增的id <insert id="insertSelective" parameterType="com.jxxx.p2pp.model.UUserInfo"> <selectKey resultType=&quo

Mybatis在insert操作时返回主键

今天在写项目的时候,遇到一个需求,就是在像数据库插入数据的时候,要保留插入数据的主键,以便后续进行级联时,可以将该主键作为另张表的外键. 但是在正常情况下我们使用插入语句返回的是int型,含义是影响该表数据的条数.但是这时候我们想要的得到的却是主键,这时候就可以对mybatis文件进行配置 如图: 属性详解: parameterType ,入参的全限定类名或类型别名 useGeneratedKeys ,取值范围true|false(默认值), 设置是否使用JDBC的getGenereatedKe

PostgreSQL使用MyBatis,insert时返回主键

MyBatis中普通的insert语句是这样的: <insert id="insert" parameterType="com.xxx.xxx.xxDo"> insert into "table_name" (key, value) values (#{key,jdbcType=VARCHAR}, #{value,jdbcType=VARCHAR}) </insert> 此时Dao接口的public Integer ins

mybatis在oracle插入对象后返回主键值

在mybatis中默认插入一条记录后,返回值为插入记录的条数. 现在想获取插入记录后,当前被插入的记录的主键值,需在insert方法中添加如下代码: <insert id="insert" parameterType="cn.com.pm.ppm.model.UserInfo" >   <selectKey resultType="java.math.BigDecimal" order="BEFORE" ke