在很多情況下,我們使用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之類帶有自動增長的數據庫。