前提條件
假設我們這里有一個 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);
}
執行后的結果


這里並不能獲取到生成的 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


方法二(推薦)
修改 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


方法三
這種方法需要在一定條件下才能使用,就是 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,所以不在這里進行測試,有興趣可以自行測試。