devil20 发表于 2018-9-22 11:05:39

Oracle的Sequence详解以及Hibernate如何使用Oracle的Sequence-linux要从娃娃抓起

一、 Hibernate介绍  Hibernate是基于对象/关系映射(ORM,Object/Relational Mapping)的一个解决方案。ORM方案的思想是将对象模型表示的对象映射到关系型数据库中,或者反之。Hibernate目前是ORM思想在Java中最成功、最强大的实现。它于2001年的年末发布第一个版本,立即引起了广泛的注意。2003年6月,Hibernate2发表,并且获得Jolt大奖,进而被JBoss吸纳成为它的一个子项目。2005年3月,Hibernate 3发表,其中做了一些比较重大的改进。本文以Hibernate3为基础编写。
  另外,Hibernate除了可以在J2EE容器中运行外,还可以运行在Java应用程序中。本文就是以Java应用程序为例来介绍它。
  二、配置开发环境
  本文以一个Java应用程序(Java Application)为例,介绍如何使用Hibernate来进行数据库操作。
  在进行Hibernate开发之前,需要首先获得Hibernate类库、相应数据库的JDBC驱动类库。Hibernate类库可以从http://www.hibernate.org中下载,目前的版本是3.0。而JDBC驱动可以根据不同的数据库来选择,在这个例子中,使用的是Oracle数据库,那么相应的JDBC驱动可以从Oracle安装目录\ora92\jdbc下获得。其他的数据库请根据相关的说明获得。
  下载Hibernate包后,可以将它解压到一个文件夹,此处假设为C:\hibernate-3.0,然后将C:\hibernate-3.0\下的hibernate.jar和C:\hibernate-3.0\lib下的那些第三方类库也放到环境变量CLASSPATH中。(通常,只需要dom4j、cglig、commons-logging、commons-collections、log4j、ehcache、asm、jta、antlr这些类库就可以了)
  做完这些配置后,就可以在此基础上进行基于Hibernate的Java程序开发了。
  三、开发基于Hibernate的应用
  现在假设我们在Oracle数据库中创建了一个表Student,它的字段如下表所示:
  字段 说明
  Student_ID 学员编号,整型,PK,自动增长
  Student_Name 学员姓名,字符串类型
  Student_Age 学员年龄,整型
  如果我们在Oracle中定义这个数据库表,我们可以定义一个创建数据库表的SQL脚本如下:
  create table Student(
  Student_ID number(6) NOT NULL PRIMARY KEY,
  Student_Name varchar2(10) NOT NULL,
  Student_Age number(2) NOT NULL
  );
  另外,因为在Oracle中没有“自动增长”类型的字段,所以通常情况下我们需要定义一个sequence来作为自动增长类型字段的数据。在这里,我们也可以定义一个sequence来给Student_ID字段提供数据。创建sequence的SQL脚本如下:
  CREATE SEQUENCE student_sequence
  INCREMENT BY 1
  START WITH 1000
  NOMAXVALUE
  NOCYCLE
  CACHE 10;
  我们在这里创建了一个student_sequence,准备用来作为Student_ID字段的值。
  接着,我们需要一个hibernate.cfg.xml或者属性文件hibernate.properties来指定Hibernate所使用的数据库以及用户名、密码等其他相关的配置,我们在此使用xml文件,它的内容如下:
  源文件:hibernate.cfg.xml
  
  
  
  
  true
  
  org.hibernate.dialect.Oracle9Dialect
  
  
  
  oracle.jdbc.driver.OracleDriver
  
  
  
  jdbc:oracle:thin:@localhost:1521:nitpro
  
  
  system
  
  manager
  
  
  做完前面的这些准备工作后,下面就让我们进入激动人心的Hibernate编程吧!
  首先,我们需要定义一个用于表示“学生”对象的Student类:
  源文件:Student.java

  public>  {
  private int student_id;
  private String student_name;
  private int student_age;
  public int getStudent_id()
  {
  return student_id;
  }
  public String getStudent_name()
  {
  return student_name;
  }
  public int getStudent_age()
  {
  return student_age;;
  }

  public void setStudent_id(int>  {

  this.student_id =>  }
  public void setStudent_name(String name)
  {
  this.student_name = name;
  }
  public void setStudent_age(int age)
  {
  this.student_age = age;
  }
  }
  这个类很简单,就是一个典型的JavaBean的定义:有三个属性:student_id、student_name和student_age,分别对应数据库表Student中的三个字段,并且在这个类中定义了对应各个属性的setter/getter方法。
  接下来,我们需要给这个类定义一个XML映射文件“Student.hbm.xml”,文件内容如下:
  源文件:Student.hbm.xml
  
  
  
  
  
  
  student_sequence
  
  
  
  
  
  
注意,在这个xml文件中,我们首先使用class元素定义了我们定义的Java类和数据库表之间的关系,在这里,我们定义的Java类和数据库表名称都是Student,然后,我们使用id元素定义了主键名称、类型等,它有一个子元素generator来说明主键的产生方式,此处指定的是“native”,表示根据数据库来选择,比如,对于Oracle数据库,它会去寻找一个sequence(默认情况下,它会去寻找一个名为“hibernate_sequence”的sequence),当然,你也可以直接将generator指定为"sequence",如果你使用的oracle数据库的话。我们可以用参数param来指定一个sequence(不指定的话,就会去找默认的名为hibernate_sequence,找不到会自己创建在数据库中创建一个hibernate_sequence)。而property用来指定Student.java类中的属性和Student数据库表之间的对应关系,以及各个字段的数据类型。在这个例子中,我们指定的数据类型是Java语言中的数据类型(此时需要指定引用类型数据),我们也可以使用Hibernate中自定义的数据类型,限于篇幅,在本文中不一一讲解。注:  1,如果使用的Oracle数据库generator配置为native,那么它默认还是以hibernate_sequence作为主键来源
  2,如果两个持久类的主键生成策略都默认是native,那这两个类的主键都会以hibernate_sequence做为主键来源,这在同一个数据库中,可能导致主键不连续的情况发生!
  然后,我们需要在hibernate.cfg.xml中加入这个文件的映射,可以在之前加入下面的语句:
  
  最后,我们需要编写一个测试类来测试一下,能否通过Hibernate和前面我们定义的相关程序,完成对数据库的操作。我们编写一个测试类如下:
  源文件:Test.java
  import org.hibernate.*;
  import org.hibernate.cfg.*;

  public>  {
  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、>  你或者是该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;原文出处:http://sunanjie1986.blog.163.com/blog/static/20928691200931495145590/
页: [1]
查看完整版本: Oracle的Sequence详解以及Hibernate如何使用Oracle的Sequence-linux要从娃娃抓起