如何通過mybatis返回oracle自增長id

 

        大家都知道像mysql,serveSql這樣的數據庫都提供有自增id的功能,而像oracle這樣的數據庫採取的是序列的方式來實現自增主鍵的,所以如果通過mybatis插入一條數據後返回主鍵id的方式也是不同的,網上有很多種說法,大都沒說太明白,下面舉個例子,詳細說明一下,避免再入坑

 

建表語句

CREATE TABLE sys_student

(

id int PRIMARY KEY NOT NULL AUTO_INCREMENT,

name varchar(50) COMMENT '名字'

);

ALTER TABLE sys_student COMMENT = '學生表';

一、mysql

 

        mysql有自增功能,可以採用useGeneratedKeys="true"開啓判斷是否是自增ID, keyProperty="id" 指定插入數據後自增ID返回時賦值給實體類的那個屬性(這裏是id屬性)

<insert id="insertStudent" useGeneratedKeys="true" keyProperty="id">

insert into sys_student(name) values(#{name})

</insert>

 

二、oracle

 

創建序列語句:

CREATE SEQUENCE student_seq

INCREMENT BY 1

START WITH 1

NOMAXVALUE

NOCYCLE ;

 

創建觸發器:

CREATE OR REPLACE TRIGGER student_trigger

BEFORE INSERT ON sys_student

FOR EACH ROW

BEGIN

SELECT student_seq.NEXTVAL INTO :NEW.id FROM DUAL;

END;

        這裏要說明一下,通常oracle實現自增,是通過觸發器實現的。先建一個序列,再建一個觸發器,每次在執行插入時,都會觸發觸發器實現自動加1。

 

像Oracle數據庫採用序列來作爲自增主鍵,可以通過 selectKey子來獲取主鍵值

<insert id="insertStudent" useGeneratedKeys="false">

<selectKey resultType="java.lang.Integer" keyProperty="id" order="BEFORE">

select student_seq.nextval from dual

</selectKey>

insert into sys_student(name) values(#{name})

</insert>

        網上很多都是這樣說的,但是最後的你可能會發現每次都自增2,而不是自增1,那麼問題出在哪了呢?

問題就出在了這句‘ select student_seq.nextval from dual’,這句的意思就是每執行一次,自增序列都會加1,如果你的oracle是通過觸發器實現的,那麼恭喜你,你會發現每插入一條數據,都會自增2,之所以這樣是因爲你執行了兩次 student_seq.nextval 。

還有一種就是利用max()函數,這種也是有問題的,而這個問題還不太容易發現,如果剛開始你的表裏一條數據都沒有,第一次執行,你會發現返回自增主鍵id,居然是null,這個問題應該也很好解決,把order="BEFORE" 改成 order="AFTER",沒準能行,我沒有試,有興趣可以自己試一下。

<insert id="insertStudent" useGeneratedKeys="false">

<selectKey resultType="java.lang.Integer"  keyProperty="id" order="BEFORE">

select max(id) from sys_student

</selectKey>

insert into sys_student(name) values(#{name})

</insert>

 

正確的方法是什麼呢?

        如果你有需要返回自增後的主鍵id,如果已經建了觸發器,那麼就刪掉觸發器,每次執行插入時,手動實現自增,如下,注意標紅的地方,如果沒有需要要返回自增id,那麼採用觸發器實現自增是完全沒有問題的。

 

刪除觸發器:

DROP TRIGGER student_trigger;

 

<insert id="insertStudent" useGeneratedKeys="false">

<selectKey resultType="java.lang.Integer" keyProperty="id" order="AFTER">

select student_seq.currval from dual

</selectKey >

insert into sys_student(id,name) values(student_seq.nextval,#{name})

</insert>

如果覺得有用,麻煩關注一下我的公衆號,謝謝

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