﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-SIMONE-随笔分类-oracle</title><link>http://www.blogjava.net/wangxinsh55/category/33868.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 19 Aug 2008 04:41:08 GMT</lastBuildDate><pubDate>Tue, 19 Aug 2008 04:41:08 GMT</pubDate><ttl>60</ttl><item><title>在hibernate中实现oracle的自动增长[转]</title><link>http://www.blogjava.net/wangxinsh55/archive/2008/08/19/222956.html</link><dc:creator>SIMONE</dc:creator><author>SIMONE</author><pubDate>Tue, 19 Aug 2008 03:43:00 GMT</pubDate><guid>http://www.blogjava.net/wangxinsh55/archive/2008/08/19/222956.html</guid><wfw:comment>http://www.blogjava.net/wangxinsh55/comments/222956.html</wfw:comment><comments>http://www.blogjava.net/wangxinsh55/archive/2008/08/19/222956.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wangxinsh55/comments/commentRss/222956.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wangxinsh55/services/trackbacks/222956.html</trackback:ping><description><![CDATA[<p><span style="font-size: 12pt;"><span style="font-family: 宋体;"><span style="font-size: 8pt;"><span style="font-size: 10pt;">在hibernate中实现oracle的自动增长 <br />
<br />
http://kuangbaoxu.javaeye.com/blog/192434<br />
<br />
关键字: hibernate oracle sequence native <br />
根据hibernate的文档，有两种方式实现实体对象的主键自动增长。 <br />
第一种：设置ID的增长策略是sequence，同时指定sequence的名字，最好每个表建一个sequence，此种做法就如同MS-SQL,MY-SQL中的自动增长一样，不需要创建触发器，具体的oracle数据库脚本及hibernate配置文件如下： <br />
<br />
<br />
[1]oracle数据表的创建脚本： <br />
Java代码</span></span></span></span></p>
<span style="font-size: 12pt;"><span style="font-family: 宋体;"><span style="font-size: 8pt;"><span style="font-size: 10pt;">CREATE TABLE DEPARTMENT (&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; ID NUMBER(19,0) DEFAULT '0' NOT NULL,&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; NAME VARCHAR2(255) NOT NULL,&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; DESCRIPTION CLOB&nbsp;&nbsp; <br />
);&nbsp;&nbsp; <br />
ALTER TABLE DEPARTMENT ADD CONSTRAINT PRIMARY_0 PRIMARY KEY(ID) ENABLE;&nbsp;&nbsp; <br />
ALTER TABLE DEPARTMENT ADD CONSTRAINT UK_DEPARTMENT_1 UNIQUE (NAME);&nbsp;&nbsp; <br />
&nbsp; <br />
CREATE SEQUENCE DEPARTMENT_ID_SEQ MINVALUE 10000 MAXVALUE 999999999999999999999999 INCREMENT BY 1 NOCYCLE;&nbsp; <br />
<br />
创建DEPARTMENT表，并为DEPARTMENT表创建一个单独的SEQUENCE，名字为SEQUENCE_ID_SEQ，并不需要创建触发器。 <br />
<br />
[2]hibernate映射文件的配置： <br />
Java代码 <br />
<br />
&lt;?xml version="1.0"?&gt;&nbsp;&nbsp; <br />
&lt;!DOCTYPE hibernate-mapping PUBLIC&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "-//Hibernate/Hibernate Mapping DTD 3.0//EN"&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"&gt;&nbsp;&nbsp; <br />
&lt;hibernate-mapping package="com.liyanframework.demo.domain"&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &lt;class name="Department" table="DEPARTMENT"&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;id name="id" column="ID"&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;generator class="sequence"&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param name="sequence"&gt;DEPARTMENT_ID_SEQ&lt;/param&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/generator&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/id&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="name" column="NAME" type="string" /&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="description" column="DESCRIPTION" type="text" /&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &lt;/class&gt;&nbsp;&nbsp; <br />
&lt;/hibernate-mapping&gt;&nbsp; <br />
<br />
在hibernate映射文件中，对ID的生成策略选择sequence，指定sequence的名字DEPARTMENT_ID_SEQ就可以了，当你
保存新对象的时候，hibernate会自动取得DEPARTMENT_ID_SEQ.NEXTVAL作为新对象的ID保存到数据库，所以不需要再使用触
发器再来生成新记录的ID。 <br />
<br />
<br />
第二种：设置ID的增长策略是native，但是需要创建一个名字为hibernate_sequence（这个名字好像是hibernate默认的
sequence名字，不创建会出错的）的全局使用的sequence，然后再对每一个表的ID生成的时候，使用触发器，取得
hibernate_sequence.CURRVAL作为新记录的ID，具体的oracle数据库脚本及hibernate配置文件如下： <br />
<br />
<br />
[1]oracle数据表的创建脚本： <br />
Java代码 <br />
<br />
<br />
CREATE TABLE STAFF (&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; ID NUMBER(19,0) DEFAULT '0' NOT NULL,&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; NAME VARCHAR2(255) NOT NULL,&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; AGE NUMBER(3,0) NOT NULL,&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; BIRTHDAY DATE NOT NULL,&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; SALARY NUMBER(10,2) NOT NULL,&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; LEVELNESS FLOAT NOT NULL,&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; CREATETIME TIMESTAMP NOT NULL,&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; ENABLE CHAR(2) DEFAULT 'Y' NOT NULL,&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; STATUS VARCHAR2(64) NOT NULL,&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; DEPARTMENT_ID NUMBER(19,0)&nbsp;&nbsp; <br />
);&nbsp;&nbsp; <br />
ALTER TABLE STAFF ADD CONSTRAINT PRIMARY_1 PRIMARY KEY(ID) ENABLE;&nbsp;&nbsp; <br />
ALTER TABLE STAFF ADD CONSTRAINT STAFF_IBFK_0 FOREIGN KEY(DEPARTMENT_ID) REFERENCES DEPARTMENT(ID) ENABLE;&nbsp;&nbsp; <br />
ALTER TABLE STAFF ADD CONSTRAINT UK_STAFF_1 UNIQUE (NAME);&nbsp;&nbsp; <br />
CREATE INDEX IDX_STAFF_STATUS ON STAFF(STATUS);&nbsp;&nbsp; <br />
&nbsp; <br />
CREATE SEQUENCE HIBERNATE_SEQUENCE MINVALUE 90000 MAXVALUE 999999999999999999999999 INCREMENT BY 1 NOCYCLE;&nbsp;&nbsp; <br />
&nbsp; <br />
CREATE OR REPLACE TRIGGER STAFF_ID_TRG BEFORE INSERT ON STAFF&nbsp;&nbsp; <br />
FOR EACH ROW&nbsp;&nbsp; <br />
BEGIN&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; IF INSERTING AND :NEW.ID IS NULL THEN&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT HIBERNATE_SEQUENCE.CURRVAL INTO :NEW.ID FROM DUAL;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; END IF;&nbsp;&nbsp; <br />
END;&nbsp; <br />
<br />
创建STAFF表，但是并没有为STAFF创建相应的主键sequence，而是创建了一个名字为HIBERNATE_SEQUENCE的
sequence，然后创建一个触发器STAFF_ID_TRG，当执行INSERT操作时，hibernate会先执行一次
HIBERNATE_SEQUENCE.NEXTVAL，所以在触发器中只需要取得HIBERNATE_SEQUENCE.CURRVAL作为新记录的
ID。 <br />
<br />
[2]hibernate映射文件的配置： <br />
Java代码 <br />
<br />
<br />
&lt;?xml version="1.0"?&gt;&nbsp;&nbsp; <br />
&lt;!DOCTYPE hibernate-mapping PUBLIC&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "-//Hibernate/Hibernate Mapping DTD 3.0//EN"&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"&gt;&nbsp;&nbsp; <br />
&lt;hibernate-mapping package="com.liyanframework.demo.domain"&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &lt;class name="Staff" table="STAFF"&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;id name="id" column="ID"&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;generator class="native" /&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/id&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="name" column="NAME" type="string" /&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="age" column="AGE" type="integer" /&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="birthday" column="BIRTHDAY" type="date" /&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="salary" column="SALARY" type="big_decimal" /&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="level" column="LEVELNESS" type="float" /&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="createTime" column="CREATETIME" type="timestamp" /&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="enable" column="ENABLE" type="character" /&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="status" column="STATUS" type="string" /&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;many-to-one name="department" column="DEPARTMENT_ID" class="Department" /&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &lt;/class&gt;&nbsp;&nbsp; <br />
&lt;/hibernate-mapping&gt;&nbsp; <br />
<br />
在hibernate映射文件中，对ID的生成策略选择native，hibernate会根据你数据库的触发器来生成新记录的ID。 <br />
</span></span></span></span><u><br />
<span style="font-size: 12pt;"><span style="font-family: 宋体;"><span style="font-size: 8pt;"><span style="font-size: 10pt;">比
较两种做法，第二种做法也就是hibernate在代码中，实现了oracle中的触发器功能。对于不同的情况，选择不懂的做法。如果新的系统，新建的
oracle数据库，推荐使用第一种做法，简单，容易移植到其他支持自动增长的数据库；如果是老的系统，需要把其他数据库转换为oracle的，那就要用
第二种了，使用native的方式，可以不改动配置文件，兼容oracle和mysql之类带有自动增长的数据库。<br />
<br />
<br />
<br />
<br />
</span></span></span></span></u>安装有oracle数据库，创建数据库，总是要创建一个主键ID，唯一标示各条记录，但oracle不支持自动编号，所以还得创建一个SEQUENCE(序列)语句如<br />
&nbsp;&nbsp;&nbsp;&nbsp;
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><span style="color: rgb(0, 0, 255);">create</span><span style="color: rgb(0, 0, 0);"> sequence bign nocycle maxvalue </span><span style="font-weight: bold; color: rgb(128, 0, 0);">9999999999</span><span style="color: rgb(0, 0, 0);"> start </span><span style="color: rgb(0, 0, 255);">with</span><span style="font-weight: bold; color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;</span><span style="color: rgb(128, 128, 128);">//</span><span style="color: rgb(0, 0, 0);">增加数据<br />
<br />
</span><span style="color: rgb(0, 0, 255);">insert</span><span style="color: rgb(0, 0, 255);">into</span><span style="color: rgb(0, 0, 255);">table</span><span style="color: rgb(0, 0, 0);"> (ID,..) </span><span style="color: rgb(0, 0, 255);">values</span><span style="color: rgb(0, 0, 0);">(bign.nextval,..)</span></div>
<br />
&nbsp;&nbsp;&nbsp;&nbsp;  在hibernate中的映射文件可这么写<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><span style="color: rgb(0, 0, 255);">&nbsp;&nbsp;  &lt;</span><span style="color: rgb(128, 0, 0);">id </span><span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">="id"</span><span style="color: rgb(255, 0, 0);"> type</span><span style="color: rgb(0, 0, 255);">="java.lang.Long"</span><span style="color: rgb(255, 0, 0);"> column</span><span style="color: rgb(0, 0, 255);">="ID"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">generator </span><span style="color: rgb(255, 0, 0);">class</span><span style="color: rgb(0, 0, 255);">="sequence"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">param </span><span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">="sequence"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">bign</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">param</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">generator</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">id</span><span style="color: rgb(0, 0, 255);">&gt;</span></div>
<br />
或<br />
<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">id </span><span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">="id"</span><span style="color: rgb(255, 0, 0);"> type</span><span style="color: rgb(0, 0, 255);">="java.lang.Long"</span><span style="color: rgb(255, 0, 0);"> column</span><span style="color: rgb(0, 0, 255);">="ID"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">generator </span><span style="color: rgb(255, 0, 0);">class</span><span style="color: rgb(0, 0, 255);">="increment"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">id</span><span style="color: rgb(0, 0, 255);">&gt;</span></div>
<p><br />
(increment 用与为long，short或者int类型生成唯一标示。只有在没有其他进程忘同一张表中插入数据时才能使用。在集群下不要使用)</p>
<img src ="http://www.blogjava.net/wangxinsh55/aggbug/222956.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wangxinsh55/" target="_blank">SIMONE</a> 2008-08-19 11:43 <a href="http://www.blogjava.net/wangxinsh55/archive/2008/08/19/222956.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>