oracle自增策略,在hibernate中實現oracle的主鍵自增策略

在很多情況下,我們使用Hibernate在已經建立好數據庫的基礎上。在oracle中,如果已經建立好的數據庫中使用了sequence,則可以按照下面的步驟把它引入到Hibernate中:

1、在oracle 首先創建sequencecreate sequence seq_id

minvalue 1

start with 1

increment by 1

cache 20;

2.在你的hbm.xml中的配置

seq_id

這樣再插入數據的時候,Hibernate回自動生成如下語句:

hibernate: select seq_id.nextval from dual

hibernate:  insert into YXJK.T_YXJK_WHRYTXL (XM0000, ZW0000, LXDH00, SJHM00, DZYJ00,

IP0000,     ID0000) values (?, ?, ?, ?, ?, ?, ?)

自動生成下一個序列值,然后將對象插入表中。

在使用的時候需要注意,Hibernate對於sequence的主鍵的要求是一定要是shor,long,或者integer

根據hibernate的文檔,有兩種方式實現實體對象的主鍵自動增長。

第一種:設置ID的增長策略是sequence,同時指定sequence的名字,最好每個表建一個sequence,此種做法就如同MS-SQL,MY-SQL中的自動增長一樣,不需要創建觸發器,具體的oracle數據庫腳本及hibernate配置文件如下:

[1]oracle數據表的創建腳本:

Java代碼

1. CREATE TABLE DEPARTMENT (

2.     ID NUMBER(19,0) DEFAULT '0' NOT NULL,

3.     NAME VARCHAR2(255) NOT NULL,

4.     DESCRIPTION CLOB

5. );

6. ALTER TABLE DEPARTMENT ADD CONSTRAINT PRIMARY_0 PRIMARY KEY(ID) ENABLE;

7. ALTER TABLE DEPARTMENT ADD CONSTRAINT UK_DEPARTMENT_1 UNIQUE (NAME);

8.

9. CREATE SEQUENCE DEPARTMENT_ID_SEQ MINVALUE 10000 MAXVALUE 999999999999999999999999 INCREMENT BY 1 NOCYCLE;復制代碼

創建DEPARTMENT表,並為DEPARTMENT表創建一個單獨的SEQUENCE,名字為SEQUENCE_ID_SEQ,並不需要創建觸發器。

[2]hibernate映射文件的配置:

Java代碼

# <?xml version="1.0"?>

# /p>

#       "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

#           "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

#

#     

#         

#            

#                 DEPARTMENT_ID_SEQ

#            

#         

#         

#         

#     

# 復制代碼

在hibernate映射文件中,對ID的生成策略選擇sequence,指定sequence的名字DEPARTMENT_ID_SEQ就可以了,當你保存新對象的時候,hibernate會自動取得DEPARTMENT_ID_SEQ.NEXTVAL作為新對象的ID保存到數據庫,所以不需要再使用觸發器再來生成新記錄的ID。

第二種:設置ID的增長策略是native,但是需要創建一個名字為hibernate_sequence(這個名字好像是hibernate默認的sequence名字,不創建會出錯的)的全局使用的sequence,然后再對每一個表的ID生成的時候,使用觸發器,取得 hibernate_sequence.CURRVAL作為新記錄的ID,具體的oracle數據庫腳本及hibernate配置文件如下:

[1]oracle數據表的創建腳本:

Java代碼

# CREATE TABLE STAFF (

#     ID NUMBER(19,0) DEFAULT '0' NOT NULL,

#     NAME VARCHAR2(255) NOT NULL,

#     AGE NUMBER(3,0) NOT NULL,

#     BIRTHDAY DATE NOT NULL,

#     SALARY NUMBER(10,2) NOT NULL,

#     LEVELNESS FLOAT NOT NULL,

#     CREATETIME TIMESTAMP NOT NULL,

#     ENABLE CHAR(2) DEFAULT 'Y' NOT NULL,

#     STATUS VARCHAR2(64) NOT NULL,

#     DEPARTMENT_ID NUMBER(19,0)

# );

# ALTER TABLE STAFF ADD CONSTRAINT PRIMARY_1 PRIMARY KEY(ID) ENABLE;

# ALTER TABLE STAFF ADD CONSTRAINT STAFF_IBFK_0 FOREIGN KEY(DEPARTMENT_ID) REFERENCES DEPARTMENT(ID) ENABLE;

# ALTER TABLE STAFF ADD CONSTRAINT UK_STAFF_1 UNIQUE (NAME);

# CREATE INDEX IDX_STAFF_STATUS ON STAFF(STATUS);

#

# CREATE SEQUENCE HIBERNATE_SEQUENCE MINVALUE 90000 MAXVALUE 999999999999999999999999 INCREMENT BY 1 NOCYCLE;

#

# CREATE OR REPLACE TRIGGER STAFF_ID_TRG BEFORE INSERT ON STAFF

# FOR EACH ROW

# BEGIN

#     IF INSERTING AND :NEW.ID IS NULL THEN

#         SELECT HIBERNATE_SEQUENCE.CURRVAL INTO :NEW.ID FROM DUAL;

#     END IF;

# END;復制代碼

創建STAFF表,但是並沒有為STAFF創建相應的主鍵sequence,而是創建了一個名字為HIBERNATE_SEQUENCE的 sequence,然后創建一個觸發器STAFF_ID_TRG,當執行INSERT操作時,hibernate會先執行一次 HIBERNATE_SEQUENCE.NEXTVAL,所以在觸發器中只需要取得HIBERNATE_SEQUENCE.CURRVAL作為新記錄的 ID。

[2]hibernate映射文件的配置:

Java代碼

# <?xml version="1.0"?>

# /p>

#       "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

#           "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

#

#     

#         

#            

#         

#         

#         

#         

#         

#         

#         

#         

#         

#         

#     

# 復制代碼

在hibernate映射文件中,對ID的生成策略選擇native,hibernate會根據你數據庫的觸發器來生成新記錄的ID。

比較兩種做法,第二種做法也就是hibernate在代碼中,實現了oracle中的觸發器功能。對於不同的情況,選擇不懂的做法。如果新的系統,新建的oracle數據庫,推薦使用第一種做法,簡單,容易移植到其他支持自動增長的數據庫;如果是老的系統,需要把其他數據庫轉換為oracle 的,那就要用第二種了,使用native的方式,可以不改動配置文件,兼容oracle和mysql之類帶有自動增長的數據庫。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值