读书人

在Hibernate中运用oracle的sequence产

发布时间: 2012-10-23 12:12:22 作者: rapoo

在Hibernate中使用oracle的sequence产生主键

<!DOCTYPE hibernate-mapping
???? PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
???? "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>????
??? <class name="Student" table="Student">????????
??????? <id name="student_id" column="student_id" type="java.lang.Integer">????????????
??????????? <generator column="Student_Name"
type="java.lang.String"/>
??????? <property name="student_age" column="Student_Age"
type="java.lang.Integer"/>
??? </class>
</hibernate-mapping>

??? 注意,在这个xml文件中,我们首先使用class元素定义了我们定义的Java类和数据库表之间的关系,在这里,我们定义的Java类和数据库表名称都是Student,然后,我们使用id元素定义了主键名称、类型等,它有一个子元素generator来说明主键的产生方式,此处指定的是“native”,表示根据数据库来选择,比如,对于Oracle数据库,它会去寻找一个sequence(默认情况下,它会去寻找一个名为“hibernate_sequence”的sequence),我们可以用参数param来指定一个sequence。而property用来指定Student.java类中的属性和Student数据库表之间的对应关系,以及各个字段的数据类型。在这个例子中,我们指定的数据类型是Java语言中的数据类型(此时需要指定引用类型数据),我们也可以使用Hibernate中自定义的数据类型,限于篇幅,在本文中不一一讲解。

??? 然后,我们需要在hibernate.cfg.xml中加入这个文件的映射,可以在</session-factory>之前加入下面的语句:

<mapping resource="Student.hbm.xml"/>
最后,我们需要编写一个测试类来测试一下,能否通过Hibernate和前面我们定义的相关程序,完成对数据库的操作。我们编写一个测试类如下:
源文件:Test.java
import org.hibernate.*;
import org.hibernate.cfg.*;

public class Test
{
??? public static void main(String[] args)
??? {
??????? try
??????? {
??????????? //通过Configuration获得一个SessionFactory对象
SessionFactory sf
= new Configuration().configure().buildSessionFactory();
??????????? //打开一个Session
??????????? Session session = sf.openSession();
??????????? //开始一个事务
??????????? Transaction tx = session.beginTransaction();
??????????? //创建一个Student对象
??????????? Student stu = new Student();
??????????? //通过Student的setter方法改变它的属性
??????????? //注意student_id不用我们设置
??????????? stu.setStudent_name("zhangsan");
??????????? stu.setStudent_age(18);
??????????? //通过session的save()方法将Student对象保存到数据库中
??????????? session.save(stu);
??????????? //提交事务
??????????? tx.commit();
??????????? //关闭会话
??????????? session.close();
??????? }
??????? catch(Exception e)
??????? {
??????????? e.printStackTrace();
??????? }
??? }???
}

??? 编译并运行这个程序,如果前面的配置和程序都没有问题,应该可以正确的往数据库表Student中插入一条数据,并且在控制台上能够得到如下输出(只列出部分输出内容):

Hibernate: select student_sequence.nextval from dual
Hibernate: insert into Student (Student_Name, Student_Age, student_id) values (?,?,?)

??? 可以看到,虽然我们自己没有编写SQL语句进行插入数据的操作,但是其实Hibernate还是要使用SQL语句来进行数据库的操作,只是这个过程对程序员来说是透明的。

??? 通过这个简单的例子,相信读者对Hibernate编程已经有了初步的了解。读者可以在此基础上进行更深入的学习。

-------------------------------------------------------------------

################################################################

在oracle中sequence就是所谓的序列号,每次取的时候它会自动增加,一般用在需要按
序列号排序的地方。

1、 create sequence
你首先要有create sequence或者create any sequence权限,
create sequence emp_sequence
?? ??? INCREMENT BY 1?? -- 每次加几个
?? ??? START WITH 1 ???? -- 从1开始计数
?? ??? NOMAXVALUE ?? -- 不设置最大值
?? ??? NOCYCLE ?? ?? ???? -- 一直累加,不循环
?? ??? CACHE 10;???????????? --预分配缓存大小为10

一旦定义了emp_sequence,你就可以用CURRVAL,NEXTVAL
CURRVAL=返回sequence的当前值
NEXTVAL=增加sequence的值,然后返回sequence值
比如:
?? ??? emp_sequence.CURRVAL
?? ??? emp_sequence.NEXTVAL

可以使用sequence的地方:
?? ??? - 不包含子查询、snapshot、VIEW的 SELECT 语句
?? ??? - INSERT语句的子查询中
?? ??? - NSERT语句的VALUES中
?? ??? - UPDATE 的 SET中

可以看如下例子:
INSERT INTO emp VALUES
(empseq.nextval, 'LEWIS', 'CLERK',7902, SYSDATE, 1200, NULL, 20);

SELECT empseq.currval FROM DUAL;

但是要注意的是:
-?? 第一次NEXTVAL返回的是初始值;随后的NEXTVAL会自动增加你定义的INCREMENT BY值,
?? 然后返回增加后的值。CURRVAL 总是返回当前sequence的值,但是在第一次NEXTVAL
?? 初始化之后才能使用CURRVAL,否则会出错。一次NEXTVAL会增加一次sequence的值,
?? 所以如果你在同一个语句里面使用多个NEXTVAL,其值就是不一样的。明白?
-?? 如果指定CACHE值,oracle就可以预先在内存里面放置一些sequence,这样存取的快
?? 些。
?? cache里面的取完后,oracle自动再取一组到cache。 使用cache或许会跳号, 比如
?? 数据库突然不正常down掉(shutdown abort),cache中的sequence就会丢失. 所以可
?? 以在create sequence的时候用nocache防止这种情况。

2、 Alter sequence
你或者是该sequence的owner,或者有ALTER ANY sequence权限才能改动sequence。 可
以alter除start值之外的所有sequence参数。如果想要改变start值,必须drop?? sequence
再re-create。例子:
ALTER sequence emp_sequence
?? ??? INCREMENT BY 10
?? ??? MAXVALUE 10000
?? ??? CYCLE -- 到10000后从头开始
?? ??? NOCACHE;

影响sequence的初始化参数:
?? ??? sequence_CACHE_ENTRIES =
?? ??? 设置能同时被cache的sequence数目。??

可以很简单的Drop sequence
DROP sequence order_seq;

读书人网 >软件架构设计

热点推荐