Mybatis 獲取自增主鍵值(Mysql,Oracle)

本文轉自:https://blog.csdn.net/yamadeee/article/details/83997122

在某些場景下,我們需要使用mybatis返回生成的主鍵值。Mybatis在insert和update標籤中就提供了這種功能。

<insert id=”indetifyId”  useGeneratedKeys=”true” keyProperty=”id” keyColumn="id">

</insert>

useGeneratedKeys: 是否自動生成主鍵,默認false
keyProperty :返回的主鍵值賦給哪個屬性
keyColumn: 數據庫中的自增主鍵的列名,默認是數據庫表的第一列。當主鍵列不是表中的第一列的時候需要設置,PostgreSQL必須設置。
主鍵自動生成,取決於數據庫是否支持自增主鍵。實際上當設置了useGeneratedKeys=“true”,Mybatis會調用JDBC的getGeneratedKeys方法,並將獲取的主鍵值賦值給keyProperty 指定的屬性。

準備
Mysql數據庫
 

create table user(
USER_ID bigint  not null auto_increment,
USER_NAME varchar(50) not null,
USER_PASSWORD varchar(30) not null,
CREATE_TIME datetime,
....
primary key(USER_ID)
)

實體

package com.test.User

public class User{
private Long userId;
private String userName;
private String userPassword;
...
setter getter....
}

mapper

public interface UserMapper{
	int insertUser(User user); //新增用戶
}

Service

@Service
public UserServiceImple implements UserService{
	@Autowired
	UserMapper userMapper;
	
	public Long inserUser(User user){
		//user數據操作,例如加密
		int inserts=userMapper.insertUser(user);
		if(inserts == 0)//插入失敗
			return -1L;
		return user.getUserId();//返回主鍵值
	}
}

獲取主鍵值

  1. 對於支持主鍵自增的數據庫(MySql)

<insert id=”insertUser”  useGeneratedKeys=”true” keyProperty=”userId” >
insert into user( 
user_name, user_password, create_time) 
values(#{userName}, #{userPassword} , #{createTime, jdbcType= TIMESTAMP})
</insert>

parameterType 可以不寫,Mybatis可以推斷出傳入的數據類型。如果想要訪問主鍵,那麼應當parameterType 應當是java實體或者Map。這樣數據在插入之後 可以通過ava實體或者Map 來獲取主鍵值。上例中就是通過 getUserId獲取主鍵

	user.getUserId()

2不支持主鍵自增的數據庫(Oracle)

對於像Oracle這樣的數據,沒有提供主鍵自增的功能,而是使用序列的方式獲取自增主鍵。可以使用<selectKey>標籤來獲取主鍵的值,這種方式不僅適用於不提供主鍵自增功能的數據庫,也適用於提供主鍵自增功能的數據庫。
select Key 一般的用法

<selectKey keyColumn="id" resultType="long" keyProperty="id" order="BEFORE">
		
</selectKey> 


下面以 oracle 爲例:
創建 Oracle 序列:

-- 創建序列, 計數開始值: 1 ; 步長:1 ; 沒有最大值, 當超過最大值時 開始從頭開始計數
create sequence USER_ID INCREMENT by 1 START WITH 1 NOMAXVALUE CYCLE;
-- 獲取當前序列號加 +1
select USER_ID.nextval from dual;
-- 獲取當前序列號
select USER_ID.currval from dual;

獲取主鍵(序列號),並插入

<insert id=”insertUser” >
		<selectKey keyColumn="id" resultType="long" keyProperty="userId" order="BEFORE">
			SELECT TO_CHAR(SYSDATE, 'yyyymmdd') || USER_ID.nextval as id from dual 
		</selectKey> 
		insert into user( 
		user_id,user_name, user_password, create_time) 
		values(#{userId},#{userName}, #{userPassword} , #{createTime, jdbcType= TIMESTAMP})
</insert>

此時會將Oracle生成的主鍵值賦予userId變量。這個userId 就是USER對象的屬性,這樣就可以將生成的主鍵值返回了。如果僅僅是在insert語句中使用但是不返回,此時keyProperty=“任意自定義變量名”,
resultType 可以不寫。
Oracle 數據庫中的值要設置爲 BEFORE ,這是因爲 Oracle中需要先從序列獲取值,然後將值作爲主鍵插入到數據庫中。

雖然說Mybatis 官方文檔說 可以推斷出 resultType類型,但是實際操作過程中。 使用實體類的屬性字段去接受selectKey的查詢結果, 沒有指明resultType 的話拋出了類似如下的異常:A query was run and no Result Maps were found for the Mapped Statement 'insertXXXX!selectKey

擴展:
如果Mysql 使用selectKey的方式獲取主鍵,需要注意下面兩點:

order : AFTER
獲取遞增主鍵值 :SELECT LAST_INSERT_ID()
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章