Mybatis 在 insert 插入操作后返回主键 id

前提条件

假设我们这里有一个 Student 表,结构如下

sid name age
101 Jone 18
102 Jack 20
103 Tom 28

其中主键 sid 是自增的,那么我们插入数据时就不用插入 sid,它会生成一个自增的 sid。


问题提出

这里有一个问题,我们执行插入语句之后,并不能获取到生成的 sid。


StudentDao 接口中的 insert 方法

boolean insertStudent(Student student);

StudentDao.xml 中的 insert 标签

<insert id="insertStudent" parameterType="Student">
    insert into student(name, age)
    VALUES (#{name} , #{age})
</insert>

单元测试类中的方法

@Test
public void insertUser() {
    Student student = new Student(0,"xxx", 28);

    boolean flag = studentDao.insertStudent(student);
    System.out.println(flag);
    System.out.println(student);
}

执行后的结果

Mybatis 在 insert 插入操作后返回主键 id_自增长Mybatis 在 insert 插入操作后返回主键 id_xml_02

这里并不能获取到生成的 sid,如果要获取这个 sid,还要根据 name 来查询数据库,而且 name 也需要是 unique 唯一性的。

那么,有没有办法让我们能够执行插入语句后,直接获取到生成的 sid 呢,当然是有的。


解决方法

方法一

修改 StudentDao.xml 中的 insert 标签,配置 useGeneratedKeys 和 keyProperty

<insert id="insertStudent" parameterType="Student" useGeneratedKeys="true" keyProperty="sid">
    insert into student(name, age)
    VALUES (#{name} , #{age})
</insert>

说明:

1、useGeneratedKeys="true" 表示给主键设置自增长。

2、keyProperty="sid" 表示将自增长后的 Id 赋值给实体类中的 sid 字段。


运行结果:成功返回了主键 sid

Mybatis 在 insert 插入操作后返回主键 id_自增长_03Mybatis 在 insert 插入操作后返回主键 id_主键_04

方法二(推荐)

修改 StudentDao.xml 中的 insert 标签,在 insert 标签中编写 selectKey 标签

<insert id="insertStudent" parameterType="Student">
    insert into student(name, age)
    VALUES (#{name} , #{age})

    <selectKey keyProperty="sid" order="AFTER" resultType="int">
        SELECT LAST_INSERT_ID()
    </selectKey>
</insert>

说明:

1、< insert> 标签中没有 resultType 属性,但是 < selectKey> 标签是有的。
2、order="AFTER" 表示先执行插入语句,之后再执行查询语句。
3、keyProperty="sid" 表示将自增长后的 Id 赋值给实体类中的 sid 字段。
4、SELECT LAST_INSERT_ID() 表示 MySQL 语法中查询出刚刚插入的记录自增长 Id。


运行结果:成功返回了主键 sid

Mybatis 在 insert 插入操作后返回主键 id_自增_05Mybatis 在 insert 插入操作后返回主键 id_xml_06

方法三

这种方法需要在一定条件下才能使用,就是 name 需要是 unique,不可重复的。

这样才能在插入后,根据 name 来查询出主键 sid。


同样是修改 StudentDao.xml 中的 insert 标签,在 insert 标签中编写 selectKey 标签

<insert id="insertStudent" parameterType="Student">
    insert into student(name, age)
    VALUES (#{name} , #{age})

    <selectKey keyProperty="sid" order="AFTER" resultType="int">
        select sid from student where name = #{name}
    </selectKey>
</insert>

原理上面也讲了,就是在执行插入语句之后,再执行查询语句,将 sid 查出来。

不过我这里 name 并未设置 unique,所以不在这里进行测试,有兴趣可以自行测试。