MyBatis實現(xiàn)主鍵返回功能的幾種方式
引言
在 MyBatis 中,當我們執(zhí)行插入操作后,經(jīng)常需要獲取數(shù)據(jù)庫生成的主鍵值(如自增ID、序列值等)。MyBatis 提供了幾種方式來實現(xiàn)主鍵返回功能。
一、主要應用場景
- 插入數(shù)據(jù)后需要立即使用生成的主鍵
- 需要將主鍵值用于后續(xù)業(yè)務邏輯或關聯(lián)操作
- 需要返回完整對象(包含主鍵)給前端
二、核心實現(xiàn)方式
1. 使用 useGeneratedKeys 和 keyProperty(推薦)
這是最常用的方式,適用于支持自動生成主鍵的數(shù)據(jù)庫(如 MySQL、SQL Server)。
XML 配置方式
<insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO user (username, email, age)
VALUES (#{username}, #{email}, #{age})
</insert>
注解配置方式
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
@Insert("INSERT INTO user (username, email, age) VALUES (#{username}, #{email}, #{{age})")
int insertUser(User user);
2. 使用 <selectKey> 元素
這種方式更靈活,適用于所有數(shù)據(jù)庫,特別是那些不支持自動生成主鍵的數(shù)據(jù)庫(如 Oracle)。
MySQL 示例
<insert id="insertUser" parameterType="User">
<selectKey keyProperty="id" resultType="java.lang.Long" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO user (username, email, age)
VALUES (#{username}, #{email}, #{age})
</insert>
Oracle 示例
<insert id="insertUser" parameterType="User">
<selectKey keyProperty="id" resultType="java.lang.Long" order="BEFORE">
SELECT user_seq.NEXTVAL FROM DUAL
</selectKey>
INSERT INTO user (id, username, email, age)
VALUES (#{id}, #{username}, #{email}, #{age})
</insert>
3. 注解方式使用 @SelectKey
@Insert("INSERT INTO user (username, email, age) VALUES (#{username}, #{email}, #{age})")
@SelectKey(statement = "SELECT LAST_INSERT_ID()", keyProperty = "id",
resultType = Long.class, before = false)
int insertUser(User user);
三、屬性詳解
1. useGeneratedKeys
- 作用:告訴 MyBatis 使用 JDBC 的
getGeneratedKeys方法來取出由數(shù)據(jù)庫內(nèi)部生成的主鍵 - 取值:true|false
- 默認值:false
2. keyProperty
- 作用:指定能夠唯一識別對象的屬性(即主鍵字段)
- 注意:如果是復合主鍵,可以用逗號分隔多個屬性名
3. keyColumn
- 作用:設置生成鍵值在表中的列名
- 注意:某些數(shù)據(jù)庫(如 PostgreSQL)必須指定,但大部分情況下 MyBatis 可以自動識別
4. <selectKey> 屬性
keyProperty:指定主鍵字段對應的屬性名resultType:主鍵的類型order:執(zhí)行順序,BEFORE|AFTERBEFORE:先獲取主鍵,再執(zhí)行插入語句AFTER:先執(zhí)行插入語句,再獲取主鍵
四、使用示例
實體類
public class User {
private Long id;
private String username;
private String email;
private Integer age;
// 構造方法、getter、setter 省略
}
Mapper 接口
public interface UserMapper {
int insertUser(User user);
@Options(useGeneratedKeys = true, keyProperty = "id")
@Insert("INSERT INTO user (username, email, age) VALUES (#{username}, #{email}, #{age})")
int insertUserWithAnnotation(User user);
}
測試代碼
// 獲取 SqlSession 和 Mapper
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 創(chuàng)建用戶對象
User user = new User();
user.setUsername("john_doe");
user.setEmail("john@example.com");
user.setAge(25);
// 執(zhí)行插入操作
int result = userMapper.insertUser(user);
// 插入成功后,主鍵會自動回填到 user 對象中
System.out.println("插入成功,生成的主鍵ID: " + user.getId());
// 此時可以直接使用 user.getId() 進行后續(xù)操作
五、不同數(shù)據(jù)庫的注意事項
MySQL
- 使用
useGeneratedKeys="true"或SELECT LAST_INSERT_ID() - 表必須具有自增主鍵
Oracle
- 需要使用序列(Sequence)
- 通常使用
order="BEFORE"
PostgreSQL
- 使用
useGeneratedKeys="true" - 可能需要指定
keyColumn
SQL Server
- 使用
useGeneratedKeys="true" - 也可以使用
SELECT SCOPE_IDENTITY()
六、最佳實踐
- 推薦使用
useGeneratedKeys:代碼更簡潔,性能更好 - 明確指定
keyProperty:避免因屬性名不一致導致的問題 - 考慮使用
keyColumn:當數(shù)據(jù)庫列名與對象屬性名不一致時特別有用 - 測試多種情況:特別是批量插入時的主鍵返回行為
- 處理復合主鍵:如果需要返回多個生成的值,可以用逗號分隔多個屬性名
<!-- 復合主鍵示例 -->
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id,version">
INSERT INTO user (...) VALUES (...)
</insert>
七、常見問題解決
主鍵沒有回填到對象中
- 檢查
keyProperty是否與實體類的屬性名一致 - 檢查數(shù)據(jù)庫是否確實生成了主鍵
批量插入時主鍵返回
- 某些數(shù)據(jù)庫可能只返回最后一個插入的主鍵
- 考慮使用
<foreach>結合<selectKey>實現(xiàn)批量主鍵返回
通過合理使用 MyBatis 的主鍵返回功能,可以大大簡化代碼并提高開發(fā)效率。
到此這篇關于MyBatis實現(xiàn)主鍵返回功能的幾種方式的文章就介紹到這了,更多相關MyBatis主鍵返回攻略內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
IntelliJ?IDEA?代碼運行時中文出現(xiàn)亂碼問題及解決方法
在我們剛接觸到IDEA時,想美滋滋的敲一個“hello?world”來問候這個世界,但難免會遇到這種問題亂碼,這篇文章主要介紹了解決IntelliJ?IDEA?代碼運行時中文出現(xiàn)亂碼問題,需要的朋友可以參考下2023-09-09
java編寫創(chuàng)建數(shù)據(jù)庫和表的程序
這篇文章主要為大家詳細介紹了java編寫創(chuàng)建數(shù)據(jù)庫和表的程序,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-10-10
詳解Java編程中final,finalize,finally的區(qū)別
這篇文章主要介紹了詳解Java編程中final,finalize,finally的區(qū)別,這個在Java面試題中簡直是太常見了...需要的朋友可以參考下2015-11-11
mybatis 根據(jù)id批量刪除的實現(xiàn)操作
這篇文章主要介紹了mybatis 根據(jù)id批量刪除的實現(xiàn)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08
Springboot整合Shiro實現(xiàn)登錄與權限校驗詳細解讀
本文給大家介紹Springboot整合Shiro的基本使用,Apache?Shiro是Java的一個安全框架,Shiro本身無法知道所持有令牌的用戶是否合法,我們將整合Shiro實現(xiàn)登錄與權限的驗證2022-04-04
Spring Boot 4.0 牽手RabbitMQ注解魔法開啟消息之旅
本文主要介紹了RabbitMQ與SpringBoot4.0的結合使用,探討了如何在SpringBoot項目中集成RabbitMQ,并通過注解方式聲明隊列、交換機和綁定關系,感興趣的朋友跟隨小編一起看看吧2026-03-03

