很多時候新增一條資料,僅僅知道操作結果(新增成功)是遠遠不夠的,更多的時候需要這條新增資料的主鍵,以便下文使用。通常的辦法是:先新增,後将其查詢出來,這在MySQL中有專門的函數可以擷取到:SELECT LAST_INSERT_ID(),顧名思義,此函數的目的是擷取最後插入的自增ID。
mybatis中通過一些設定可以将insert的資料的主鍵傳回,直接拿到新增資料的主鍵,以便後續使用,主要有兩種場景,分别針對mysql和oracle進行設定。
使用@Options注解(userGeneratedKeys和keyProperty屬性)擷取主鍵
我們可以使用@Options注解的userGeneratedKeys和keyProperty屬性讓資料庫産生auto_increment(自增長)列的值,然後将生成的值設定到輸入參數對象的屬性中。@Insert("INSERT INTO STUDENTS(NAME,EMAIL,ADRESS,PHONE)
VALUES(#{name},#{email},#{address},#{phone})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insertStudent(Student student);
這裡ID列值将會通過MySQL資料庫自動生成。并且生成的值将會被設定到student對象的Id屬性中。StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
mapper.insertStudent(student);
int studentId = student.getId();
使用@SelectKey注解擷取主鍵
有一些資料庫如Oracle,并不支援AUTO_INCREMENT列屬性,它使用序列(SEQUENCE)來産生主鍵的值。我們可以使用@SelectKey注解來為任意SQL語句來指定主鍵值,作為主鍵列的值。
假設我們有一個名為STUD_ID_SEQ的序列來生成ID主鍵值。@Insert("INSERT INTO STUDENTS(ID,NAME,EMAIL,ADDR,PHONE)
VALUES(#{id},#{name},#{email},#{address},#{phone})")
@SelectKey(statement="SELECT STUD_ID_SEQ.NEXTVAL FROM DUAL",
keyProperty="id", resultType=int.class, before=true)
int insertStudent(Student student);
這裡我們使用了@SelectKey來生成主鍵值,并且存儲到了student對象的id屬性上。由于我們設定了before=true,該語句将會在執行INSERT語句之前執行。
如果你使用序列作為觸發器來設定主鍵值,我們可以在INSERT語句執行後,從sequence_name.currval擷取資料庫産生的主鍵值。@Insert("INSERT INTO STUDENTS(NAME,EMAIL,ADDR,PHONE)
VALUES(#{name},#{email},#{address},#{phone})")
@SelectKey(statement="SELECT STUD_ID_SEQ.CURRVAL FROM DUAL",
keyProperty="id", resultType=int.class, before=false)
int insertStudent(Student student);
補充說明:非自增主鍵的擷取方法
設計表的時候有兩種主鍵,一種自增主鍵,一般為int類型,一種為非自增的主鍵,例如用uuid等。下面來講講非自增主鍵的擷取方法。大緻一樣,些許不同。@Insert("INSERT INTO STUDENTS(ID,NAME,EMAIL,ADDR,PHONE)
VALUES(#{id},#{name},#{email},#{address},#{phone})")
@SelectKey(statement="SELECT UUID()",
keyProperty="id", resultType=String.class, before=true)
int insertStudent(Student student);
跟自增主鍵方式相比,這裡的不同之處隻有三點:insert語句需要寫id字段了,并且values裡面也不能省略。
selectKey的order屬性需要寫成BEFORE,因為這樣才能将生成的uuid主鍵放入到user中,這樣後面的insert的values裡面的id才不會擷取為空。
跟自增主鍵相比就這點差別,這裡的擷取主鍵id的方式為select uuid() 。