掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
根據(jù)hibernate的文檔,有兩種方式實現(xiàn)實體對象的主鍵自動增長。

創(chuàng)新互聯(lián)建站專業(yè)為企業(yè)提供婁底網(wǎng)站建設(shè)、婁底做網(wǎng)站、婁底網(wǎng)站設(shè)計、婁底網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、婁底企業(yè)網(wǎng)站模板建站服務(wù),十余年婁底做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。
***種:設(shè)置ID的增長策略是sequence,同時指定sequence的名字,***每個表建一個sequence,此種做法就如同MS-SQL,MY-SQL中的自動增長一樣,不需要創(chuàng)建觸發(fā)器,具體的oracle數(shù)據(jù)庫腳本及hibernate配置文件如下:
[1]oracle數(shù)據(jù)表的創(chuàng)建腳本:
- CREATE TABLE DEPARTMENT (
- ID NUMBER(19,0) DEFAULT '0' NOT NULL,
- NAME VARCHAR2(255) NOT NULL,
- DESCRIPTION CLOB
- );
- ALTER TABLE DEPARTMENT ADD CONSTRAINT PRIMARY_0 PRIMARY KEY(ID) ENABLE;
- ALTER TABLE DEPARTMENT ADD CONSTRAINT UK_DEPARTMENT_1 UNIQUE (NAME);
- CREATE SEQUENCE DEPARTMENT_ID_SEQ MINVALUE 10000 MAXVALUE 999999999999999999999999 INCREMENT BY 1 NOCYCLE;
創(chuàng)建DEPARTMENT表,并為DEPARTMENT表創(chuàng)建一個單獨的SEQUENCE,名字為SEQUENCE_ID_SEQ,并不需要創(chuàng)建觸發(fā)器。
[2]hibernate映射文件的配置:
- < ?xml version="1.0"?>
- < !DOCTYPE hibernate-mapping PUBLIC
- "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- < hibernate-mapping package="com.liyanframework.demo.domain">
- < class name="Department" table="DEPARTMENT">
- < id name="id" column="ID">
- < generator class="sequence">
- < param name="sequence">DEPARTMENT_ID_SEQ< /param>
- < /generator>
- < /id>
- < property name="name" column="NAME" type="string" />
- < property name="description" column="DESCRIPTION" type="text" />
- < /class>
- < /hibernate-mapping>
在hibernate映射文件中,對ID的生成策略選擇sequence,指定sequence的名字DEPARTMENT_ID_SEQ就可以了,當(dāng)你保存新對象的時候,hibernate會自動取得DEPARTMENT_ID_SEQ.NEXTVAL作為新對象的ID保存到數(shù)據(jù)庫,所以不需要再使用觸發(fā)器再來生成新記錄的ID。
第二種:設(shè)置ID的增長策略是native,但是需要創(chuàng)建一個名字為hibernate_sequence(這個名字好像是hibernate默認(rèn)的 sequence名字,不創(chuàng)建會出錯的)的全局使用的sequence,然后再對每一個表的ID生成的時候,使用觸發(fā)器,取得 hibernate_sequence.CURRVAL作為新記錄的ID,具體的oracle數(shù)據(jù)庫腳本及hibernate配置文件如下:
[1]oracle數(shù)據(jù)表的創(chuàng)建腳本:
- 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;
創(chuàng)建STAFF表,但是并沒有為STAFF創(chuàng)建相應(yīng)的主鍵sequence,而是創(chuàng)建了一個名字為HIBERNATE_SEQUENCE的 sequence,然后創(chuàng)建一個觸發(fā)器STAFF_ID_TRG,當(dāng)執(zhí)行INSERT操作時,hibernate會先執(zhí)行一次 HIBERNATE_SEQUENCE.NEXTVAL,所以在觸發(fā)器中只需要取得HIBERNATE_SEQUENCE.CURRVAL作為新記錄的 ID。
[2]hibernate映射文件的配置:
- < ?xml version="1.0"?>
- < !DOCTYPE hibernate-mapping PUBLIC
- "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- < hibernate-mapping package="com.liyanframework.demo.domain">
- < class name="Staff" table="STAFF">
- < id name="id" column="ID">
- < generator class="native" />
- < /id>
- < property name="name" column="NAME" type="string" />
- < property name="age" column="AGE" type="integer" />
- < property name="birthday" column="BIRTHDAY" type="date" />
- < property name="salary" column="SALARY" type="big_decimal" />
- < property name="level" column="LEVELNESS" type="float" />
- < property name="createTime" column="CREATETIME" type="timestamp" />
- < property name="enable" column="ENABLE" type="character" />
- < property name="status" column="STATUS" type="string" />
- < many-to-one name="department" column="DEPARTMENT_ID" class="Department" />
- < /class>
- < /hibernate-mapping>
在hibernate映射文件中,對ID的生成策略選擇native,hibernate會根據(jù)你數(shù)據(jù)庫的觸發(fā)器來生成新記錄的ID。
比較兩種做法,第二種做法也就是hibernate在代碼中,實現(xiàn)了oracle中的觸發(fā)器功能。對于不同的情況,選擇不懂的做法。如果新的系統(tǒng),新建的 oracle數(shù)據(jù)庫,推薦使用***種做法,簡單,容易移植到其他支持自動增長的數(shù)據(jù)庫;如果是老的系統(tǒng),需要把其他數(shù)據(jù)庫轉(zhuǎn)換為oracle的,那就要用第二種了,使用native的方式,可以不改動配置文件,兼容oracle和mysql之類帶有自動增長的數(shù)據(jù)庫。
安裝有oracle數(shù)據(jù)庫,創(chuàng)建數(shù)據(jù)庫,總是要創(chuàng)建一個主鍵ID,唯一標(biāo)示各條記錄,但oracle不支持自動編號,所以還得創(chuàng)建一個SEQUENCE(序列)語句如
create sequence bign nocycle maxvalue 9999999999 start with1;//增加數(shù)據(jù)
insertintotable (ID,..) values(bign.nextval,..)
在hibernate中的映射文件可這么寫
- < id name="id" type="java.lang.Long" column="ID">
- < generator class="sequence">
- < param name="sequence">bign< /param>
- < /generator>
- < /id>
或
- < id name="id" type="java.lang.Long" column="ID">
- < generator class="increment">
- < /id>
(increment 用與為long,short或者int類型生成唯一標(biāo)示。只有在沒有其他進(jìn)程忘同一張表中插入數(shù)據(jù)時才能使用。在集群下不要使用)

我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流