Hibernate标识符属性生成策略与对象识别
- 格式:doc
- 大小:183.00 KB
- 文档页数:17
∙∙∙∙关注此空间 964zyz2012-01-13 09:31JPA实体注解与hibernate主键生成策略用hibernate注解开发项目,对于主键的生成策略有些模糊,下面是从新浪网里面看到的一篇关于hibernate注解以及主键生成策略的文章,值得一看:1. 实体标志:@Entity@Indexed(index="group")@Table(name="GROUP_LAYMOD")* @Indexed 标识需要进行索引的对象,* 属性 : index 指定索引文件的路径 @DocumentId 用于标示实体类中的唯一的属性保存在索引文件中,是当进行全文检索时可以这个唯一的属性来区分索引中其他实体对象,一般使用实体类中的主键属性* @Field 标注在类的get属性上,标识一个索引的Field属性 : index 指定是否索引,与Lucene相同store 指定是否索引,与Lucene相同name 指定Field的name,默认为类属性的名称analyzer 指定分析器在hibernate注解主键的时候,一般会使用到这两个。
@GeneratedValue的作用是JPA的默认实现自定义主键生成策略@GenericGenerator是hibernate在JPA的基础上增强。
自定义主键生成策略,由@GenericGenerator实现。
hibernate在JPA的基础上进行了扩展,可以用一下方式引入hibernate独有的主键生成策略,就是通过@GenericGenerator加入的。
比如说,JPA标准用法@Id@GeneratedValue(GenerationType.AUTO)就可以用hibernate特有以下用法来实现@GeneratedValue(generator = "paymentableGenerator")@GenericGenerator(name = "paymentableGenerator", strategy = "assigned")@GenericGenerator的定义:@Target({PACKAGE, TYPE, METHOD, FIELD})@Retention(RUNTIME)public @interface GenericGenerator {String name();String strategy();Parameter[] parameters() default {};}name属性指定生成器名称。
Hibernate教程---看这⼀篇就够了1 Hibernate概述1.1什么是hibernate框架(重点)1 hibernate框架应⽤在javaee三层结构中 dao层框架2 在dao层⾥⾯做对数据库crud操作,使⽤hibernate实现crud操作,hibernate底层代码就是jdbc,hibernate对jdbc进⾏封装,使⽤hibernate好处,不需要写复杂jdbc代码了,不需要写sql语句实现3 hibernate开源的轻量级的框架4 hibernate版本Hibernate3.xHibernate4.xHibernate5.x(学习)1.2 什么是orm思想(重点)1 hibernate使⽤orm思想对数据库进⾏crud操作2 在web阶段学习 javabean,更正确的叫法实体类3 orm:object relational mapping,对象关系映射⽂字描述:(1)让实体类和数据库表进⾏⼀⼀对应关系让实体类⾸先和数据库表对应让实体类属性和表⾥⾯字段对应(2)不需要直接操作数据库表,⽽操作表对应实体类对象画图描述2 Hibernate⼊门2.1 搭建hibernate环境(重点)第⼀步导⼊hibernate的jar包因为使⽤hibernate时候,有⽇志信息输出,hibernate本⾝没有⽇志输出的jar包,导⼊其他⽇志的jar包不要忘记还有mysql驱动的jar包第⼆步创建实体类package cn.itcast.entity;public class User {/*hibernate要求实体类有⼀个属性唯⼀的*/// private int uid;private String uid;private String username;private String password;private String address;// public int getUid() {// return uid;// }// public void setUid(int uid) {// this.uid = uid;// }public String getUsername() {return username;}public String getUid() {return uid;}public void setUid(String uid) {this.uid = uid;}public void setUsername(String username) {ername = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}}(1)使⽤hibernate时候,不需要⾃⼰⼿动创建表,hibernate帮把表创建第三步配置实体类和数据库表⼀⼀对应关系(映射关系)使⽤配置⽂件实现映射关系(1)创建xml格式的配置⽂件- 映射配置⽂件名称和位置没有固定要求- 建议:在实体类所在包⾥⾯创建,实体类名称.hbm.xml(2)配置是是xml格式,在配置⽂件中⾸先引⼊xml约束- 学过约束dtd、schema,在hibernate⾥⾯引⼊的约束dtd约束(3)配置映射关系<hibernate-mapping><!-- 1 配置类和表对应class标签name属性:实体类全路径table属性:数据库表名称--><class name="er" table="t_user"><!-- 2 配置实体类id和表id对应hibernate要求实体类有⼀个属性唯⼀值hibernate要求表有字段作为唯⼀值--><!-- id标签name属性:实体类⾥⾯id属性名称column属性:⽣成的表字段名称--><id name="uid" column="uid"><!-- 设置数据库表id增长策略native:⽣成表id值就是主键⾃动增长--><generator class="native"></generator></id><!-- 配置其他属性和表字段对应name属性:实体类属性名称column属性:⽣成表字段名称--><property name="username" column="username"></property><property name="password" column="password"></property><property name="address" column="address"></property></class></hibernate-mapping>第四步创建hibernate的核⼼配置⽂件(1)核⼼配置⽂件格式xml,但是核⼼配置⽂件名称和位置固定的- 位置:必须src下⾯- 名称:必须hibernate.cfg.xml(2)引⼊dtd约束(3)hibernate操作过程中,只会加载核⼼配置⽂件,其他配置⽂件不会加载第⼀部分:配置数据库信息必须的第⼆部分:配置hibernate信息可选的第三部分:把映射⽂件放到核⼼配置⽂件中<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""/dtd/hibernate-configuration-3.0.dtd"><hibernate-configuration><session-factory><!-- 第⼀部分:配置数据库信息必须的 --><property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql:///hibernate_day01</property> <property name="ername">root</property><property name="hibernate.connection.password">root</property><!-- 第⼆部分:配置hibernate信息可选的--><!-- 输出底层sql语句 --><property name="hibernate.show_sql">true</property><!-- 输出底层sql语句格式 --><property name="hibernate.format_sql">true</property><!-- hibernate帮创建表,需要配置之后update: 如果已经有表,更新,如果没有,创建--><property name="hibernate.hbm2ddl.auto">update</property><!-- 配置数据库⽅⾔在mysql⾥⾯实现分页关键字 limit,只能使⽤mysql⾥⾯在oracle数据库,实现分页rownum让hibernate框架识别不同数据库的⾃⼰特有的语句--><property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property><!-- 第三部分:把映射⽂件放到核⼼配置⽂件中必须的--><mapping resource="cn/itcast/entity/User.hbm.xml"/></session-factory></hibernate-configuration>2.2 实现添加操作第⼀步加载hibernate核⼼配置⽂件第⼆步创建SessionFactory对象第三步使⽤SessionFactory创建session对象第四步开启事务第五步写具体逻辑 crud操作第六步提交事务第七步关闭资源@Testpublic void testAdd() {// 第⼀步加载hibernate核⼼配置⽂件// 到src下⾯找到名称是hibernate.cfg.xml//在hibernate⾥⾯封装对象Configuration cfg = new Configuration();cfg.configure();// 第⼆步创建SessionFactory对象//读取hibernate核⼼配置⽂件内容,创建sessionFactory//在过程中,根据映射关系,在配置数据库⾥⾯把表创建SessionFactory sessionFactory = cfg.buildSessionFactory(); // 第三步使⽤SessionFactory创建session对象// 类似于连接Session session = sessionFactory.openSession();// 第四步开启事务Transaction tx = session.beginTransaction();// 第五步写具体逻辑 crud操作//添加功能User user = new User();user.setUsername("⼩王");user.setPassword("250");user.setAddress("⽇本");//调⽤session的⽅法实现添加session.save(user);// 第六步提交事务mit();// 第七步关闭资源session.close();sessionFactory.close();}3 内容⽬录1 实体类编写规则2 hibernate主键⽣成策略(1)native(2)uuid3 实体类操作(1)crud操作(2)实体类对象状态4 hibernate的⼀级缓存5 hibernate的事务操作(1)事务代码规范写法6 hibernate其他的api(查询)(1)Query(2)Criteria(3)SQLQuery3.1 实体类编写规则1 实体类⾥⾯属性私有的2 私有属性使⽤公开的set和get⽅法操作3 要求实体类有属性作为唯⼀值(⼀般使⽤id值)4 实体类属性建议不使⽤基本数据类型,使⽤基本数据类型对应的包装类(1)⼋个基本数据类型对应的包装类- int – Integer- char—Character、- 其他的都是⾸字母⼤写⽐如 double – Double(2)⽐如表⽰学⽣的分数,假如 int score;- ⽐如学⽣得了0分,int score = 0;- 如果表⽰学⽣没有参加考试,int score = 0;不能准确表⽰学⽣是否参加考试l 解决:使⽤包装类可以了, Integer score = 0,表⽰学⽣得了0分,表⽰学⽣没有参加考试,Integer score = null;3.2 Hibernate主键⽣成策略1 hibernate要求实体类⾥⾯有⼀个属性作为唯⼀值,对应表主键,主键可以不同⽣成策略2 hibernate主键⽣成策略有很多的值3 在class属性⾥⾯有很多值(1)native:根据使⽤的数据库帮选择哪个值(2)uuid:之前web阶段写代码⽣成uuid值,hibernate帮我们⽣成uuid值3.3 实体类操作对实体类crud操作添加操作1 调⽤session⾥⾯的save⽅法实现根据id查询1 调⽤session⾥⾯的get⽅法实现修改操作1 ⾸先查询,修改值(1)根据id查询,返回对象删除操作1 调⽤session⾥⾯delete⽅法实现3.4 实体类对象状态(概念)1 实体类状态有三种(1)瞬时态:对象⾥⾯没有id值,对象与session没有关联(2)持久态:对象⾥⾯有id值,对象与session关联(3)托管态:对象有id值,对象与session没有关联2 演⽰操作实体类对象的⽅法(1)saveOrUpdate⽅法:实现添加、实现修改3.5 Hibernate的⼀级缓存什么是缓存1 数据存到数据库⾥⾯,数据库本⾝是⽂件系统,使⽤流⽅式操作⽂件效率不是很⾼。
目录1.1应用Hibernate框架时所应该注意的问题 (2)1.1.1开发要点 (2)1.1.2持久化类的基本结构要求 (6)1.1.3关于数据验证的问题 (9)1.1.4区分各种数据类型之间的差别 (16)1.1应用Hibernate框架时所应该注意的问题1.1.1开发要点1、PO与DTO的各自的应用要点(1)应该避免直接PO传递到系统中的其他层面在传统的MVC架构中,位于持久层的PO,是否允许被传递到其他层面如表示层或者业务层?由于PO的更新最终将被映射到实际数据库中,如果PO在其他层面(如表示层)发生了变动,那么可能会对Model层造成意想不到的破坏。
因此,一般而言,应该避免直接PO传递到系统中的其他层面。
(2)利用DTO(实现了java.io.Serializable接口的VO)一种解决办法是,通过一个VO,通过属性复制使其具备与PO相同属性值,并以其作为传输媒质(实际上,这个VO被用作Data Transfer Object,即所谓的DTO),将此VO(或者DTO)传递给其它层面以实现必须的数据传送。
(3)属性复制的方法属性复制可以通过Apache Jakarta Commons Beanutils (/commons/beanutils/)组件提供的属性批量复制功能,避免繁复的get/set操作。
UserInfo oneUserInfoPO=(UserInfo)resultList.get(0);oneUserInfoVO.setUserID(oneUserInfoPO.getId().intValue());oneUserInfoVO.setUserName(oneUserInfoPO.getUserName());oneUserInfoVO.setUserPassWord(oneUserInfoPO.getUserPassWord());oneUserInfoVO.setUserType(oneUserInfoPO.getUserType());oneUserInfoVO.setAliaoName(oneUserInfoPO.getAliaoName());oneUserInfoVO.setPassWordAsk(oneUserInfoPO.getPassWordAsk());oneUserInfoVO.setUserImage(oneUserInfoPO.getUserImage());oneUserInfoVO.setPassWordAnswer(oneUserInfoPO.getPassWordAnswer());oneUserInfoVO.setUserMail(oneUserInfoPO.getUserMail());oneUserInfoVO.setRegisterTime(oneUserInfoPO.getRegisterTime());可以在/commons/beanutils/downloads.html进行下载下面的例子中,我们把zhang对象的所有属性复制到wang对象中,然后将wang设计为DTO:UserInfo zhang=new UserInfo();UserInfo wang=new UserInfo();zhang.setName("zhang");zhang.setUserType(1);try{BeanUtils.copyProperties(wang,zhang);System.out.println("UserName=>"+wang.getName());System.out.println("UserType=>"+wang.getUserType());}catch(IllegalAccessException e){e.printStackTrace();}catch(InvocationTargetException e){e.printStackTrace();}2、持久化类中的id属性(1)对象标识符(OID,Object Identifier)前面例中的Book持久化类有一个id属性,用来惟一标识Book类的每个对象。
Hibernate中ID生成策略-电脑资料四、ID生成策略第一种:XML配置ID通过为元素增加子元素,该子元素拥有class属性,。
常用的class属性有:(1)increment:用于为long、short、或者int类型生成唯一标识。
只有在没有其他进程往同一张表中插入数据的时候才能使用。
在集群不要使用。
(极少使用)(2)native:让数据库自动选择identity,sequence,或者其他。
(3)uuid:128位的UUID算法,产生String类型ID(4)identity:对于DB2、MySQL、SQL Server、Sybase和HypersonicSQL的内置标识字段提供支持。
返回的标识符是long、short或者int类型。
sequence:在Oracel,PostgreSQL,SAP,DB,Mckio中使用序列(sequence),而在Interbase中使用生成器(generator),返回的标识符是long、short或者是int类型。
小实验1:(1)创建Student.javapackage com.zgy.hibernate.model;public class Student {private String id;private String name;private int age;private int score;public int getScore() {return score;}public void setScore(int score) {this.score = score;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) { = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}(2)在Student.hbm.xml中,为配置其generator的class为uuid"-//Hibernate/Hibernate Mapping DTD 3.0//EN""/dtd/hibernate-mapping-3.0.dtd">(3)测试package com.zgy.hibernate.model;import static org.junit.Assert.*;import java.util.Date;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.AnnotationConfiguration;import org.junit.AfterClass;import org.junit.BeforeClass;import org.junit.Test;public class HibernateIDTest {public static SessionFactory sf = null;@BeforeClasspublic static void beforeClass(){sf = new AnnotationConfiguration().configure().buildSessionFactory();}@Testpublic void testStudent() {Student s = new Student();s.setName("张三");s.setAge(20);s.setScore(90);Session session = sf.openSession();session.beginTransaction();session.save(s);session.getTransaction().commit();session.close();}@AfterClasspublic static void afterClass(){sf.close();}}(4)验证select * from student;+-----------------------------------------------+--------+------+------+| id | name | age | score |+------------------------------------------------+------+-------+------+| 4028dae54aa322d1014aa322d5a50000 | 张三 | 20 | 90 |+----------------------------------+------+-----+-------+------+------+desc student;数据插入成功,id类型为varchar(255),主键小实验2:(1)修改Student.java。
Hibernate各种主键生成策略与配置详解目录Hibernate各种主键生成策略与配置详解 (1)1、assigned (2)2、increment (2)3、hilo (2)4、seqhilo (3)5、sequence (4)6、identity (4)7、native (4)8、uuid (5)9、guid (5)10、foreign (6)11、select (6)12、其他注释方式配置 (6)13、小结 (7)1、assigned主键由外部程序负责生成,在 save() 之前必须指定一个。
Hibernate不负责维护主键生成。
与Hibernate和底层数据库都无关,可以跨数据库。
在存储对象前,必须要使用主键的setter方法给主键赋值,至于这个值怎么生成,完全由自己决定,这种方法应该尽量避免。
注释方式“ud”是自定义的策略名,人为起的名字,后面均用“ud”表示。
特点:可以跨数据库,人为控制主键生成,应尽量避免。
2、increment由Hibernate从数据库中取出主键的最大值(每个session只取1次),以该值为基础,每次增量为1,在内存中生成主键,不依赖于底层的数据库,因此可以跨数据库。
Hibernate调用org.hibernate.id.IncrementGenerator类里面的generate()方法,使用select max(idColumnName) from tableName语句获取主键最大值。
该方法被声明成了synchronized,所以在一个独立的Java虚拟机内部是没有问题的,然而,在多个JVM同时并发访问数据库select max时就可能取出相同的值,再insert就会发生Dumplicate entry的错误。
所以只能有一个Hibernate应用进程访问数据库,否则就可能产生主键冲突,所以不适合多进程并发更新数据库,适合单一进程访问数据库,不能用于群集环境。
Hibernate的原理与配置快速入门Type一个重要的术语:TypeHibernate的设计者们发明了一个术语:Type,它在整个构架中是一个非常基础、有着强大功能的元素。
一个Type对象能将一个Java 类型映射到数据库中一个表的字段中去(实际上,它可以映射到表的多个字段中去)。
持久类的所有属性都对应一个type。
这种设计思想使用Hibernate有着高度的灵活性和扩展性。
Hibernate内置很多type类型,几乎包括所有的Java基本类型,例如Java.util.Currency、Java.util.calendar、byte[]和Java.io.Serializable。
不仅如此,Hibernate还支持用户自定义的type,通过实现接口UserType和接口CompositeUserType,你可以加入自己的type。
你可以利用这种特色让你的项目中使用自定义的诸如Address、Name 这样的type,这样你就可以获得更大的便利,让你的代码更优雅。
自定义type在Hibernate中是一项核心特色,它的设计者鼓励你多多使用它来创建一个灵活、优雅的项目!策略接口Hibernate与某些其它开源软件不同的还有一点――高度的可扩展性,这通过它的内置策略机制来实现。
当你感觉到Hibernate的某些功能不足,或者有某些缺陷时,你可以开发一个自己的策略来替换它,而你所要做的仅仅只是继承它的某个策略接口,然后实现你的新策略就可以了,以下是它的策略接口:· 主键的生成 (IdentifierGenerator 接口)· 本地SQL语言支持 (Dialect 抽象类)· 缓冲机制 (Cache 和CacheProvider 接口)· JDBC 连接管理 (ConnectionProvider接口)· 事务管理(TransactionFactory, Transaction, 和TransactionManagerLookup 接口)· ORM 策略 (ClassPersister 接口)· 属性访问策略 (PropertyAccessor 接口)· 代理对象的创建 (ProxyFactory接口)Hibernate为以上所列的机制分别创建了一个缺省的实现,因此如果你只是要增强它的某个策略的功能的话,只需简单地继承这个类就可以了,没有必要从头开始写代码。
Hibernate使用技巧很多程序员认为一旦使用类似Hibernate这样的对象关系映射工具(object-relational mapping tool)就不用去担心持久化问题了,神奇的Hibernate会处理好所有的事情。
但是事实上可能刚好相反。
正因为使用Hibernate这样的技术,程序员才更应该清楚的明白域对象(domain object)以及如何获取这些对象。
这方面的错误同样会导致数据库发生异常。
使用Hibernate 使得程序员可以忽略对象和关系结构之间的不一致,但这也意味着,如果你要求它去做些傻事,它也会毫不犹豫的去做。
比如可怕的n+1错误。
请记住,Hibernate可以做很多事情,但不能帮你写代码。
这篇文章总结了我使用Hibernate的一些经验,以及在使用过程中学习到的一些技术技巧和知识。
如何定义实体持久化策略(或许也是整个应用)中最重要的就是实体定义。
所有的对象都是从核心对象集合中繁衍而来的,因此正确的定义实体是非常重要的。
下面是构建Hibernate/JPA实体方面我的一些建议。
1. 创建一个新类,实现java.io.Serializable接口(并且显式定义serialVersionUID这个变量)。
2. 增加类变量@Id Serializable id 和@Version Date lastUpdated。
这两个变量分别是数据库主键(primary key)和实现乐观锁(optimistic locking)的版本号标记。
3. 增加任何需要的属性。
4. 写一个缺省的构造器。
所有的类型的变量都应该在这里初始化,包括集合(Collection),列表(List),集合(Set)等等5. 为所有的属性创建getter和setter方法:a) 应该为id和lastUpdated创建public getter方法,但是不要创建setter方法。
b) 应该为Collection、List、Set等类型的变量创建public getter方法,但不要创建setter 方法。
Hibernate配置文件中映射元素详解添加时刻:2007-4-22本文中将讲述Hibernate的大体配置及配置文件的应用,这关于正确熟练利用Hibernate是相当关键的。
配置文件中映射元素详解对象关系的映射是用一个XML文档来讲明的。
映射文档能够利用工具来生成,如XDoclet,Middlegen 和AndroMDA等。
下面从一个映射的例子开始讲解映射元素,映射文件的代码如下。
<?xml version="1.0"?><!--所有的XML映射文件都需要定义如下所示的DOCTYPE。
Hibernate会先在它的类路径(classptah)中搜索DTD文件。
--><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""http:///hibernate-mapping-3.0.dtd"><!--hibernate-mapping有几个可选的属性:schema属性指明了这个映射的表所在的schema名称。
default-cascade属性指定了默认的级联风格可取值有none、save、update。
auto-import属性默认让我们在查询语言中可以使用非全限定名的类名可取值有true、false。
package属性指定一个包前缀。
--><hibernate-mapping schema="schemaName" default-cascade="none"auto-import="true" package="test"><!--用class元素来定义一个持久化类--><class name="People" table="person"><!-- id元素定义了属性到表主键字段的映射。
第3章标识符属性生成策略与对象识别3.1 数据库中的主键在数据库表中能够唯一识别每一条记录的一个字段或者多个字段的组合,称之为主键(Primary Key)。
主键的主要作用将表中记录的数据和其他表中的数据进行关联。
作为主键的需要满足如下的条件:主键值所在的字段不能为null。
主键值具有唯一性,不能重复。
主键必须简洁,不要包含过多属性。
表中的主键通过数据库DDL语句设置的,主键又可以分为自然主键(Natrual Key)和代理主键。
3.1.1 自然主键在数据库表中把具有业务逻辑含义的字段作为主键,称为"自然主键(Natural Key)"。
例如,如果有一个employee表,保存某个公司所有员工的基本信息,其中员工的身份证号具有唯一性,所以可以使用身份证号作为这个表的主键,还可以通过两个或者多个字段的组合作为主键,称为"复合主键"。
例如,在employee表中,因为姓名和出生日期字段组合后也具有唯一性,所以其组合也可以作为employee表的复合主键。
数据库中表与表通过主键与外键进行关联,修改表中的主键值会对数据库中数据的维护带来非常大的麻烦,应该尽量避免被修改,但是由于自然主键也表示了表中的业务逻辑信息,所以存在一定的被修改概率。
例如:在某些运行系统中,如果数据库的某些表使用身份证号作为主键,则在最近的这次身份证号码从15位升级到18位的过程中,增加了不必要的系统升级的工作量。
在数据库设计中应该尽量避免使用自然主键,而使用代理主键。
3.1.2 代理主键在数据库表中采用一个与当前表中逻辑信息无关的字段作为其主键,即代理主键这样的主键一般可以采用数据库中自动增长的生成机制自动生成主键值,字段名通常命名为"i d"。
例如,在Oracle数据库中主键值即可采用序列生成;在MySQL和MS SQL Server数据库中代理主键的字段类型设置为自动增长(auto increment)类型,数据类型一般为整形(Integer)。
3.2 标识符属性在数据库表中通过使用主键实现记录识别的唯一性,而Hibernate中的持久化对象则通过标识符(identifier)属性来实现唯一性识别。
Hibernate中的标识符属性也可以称为"Hibernate主键"它赋予每个持久化对象独一无二的数值,所以可以认为标识符属性是数据库主键的等价物。
3.3 标识符属性的生成策略Hibernate映射文件(*.hbm.xml)中的<id>元素定义持久化类的标识符属性名、类型和与数据库表中字段的映射,其<generator>子元素则用来设置当前持久化类的标识符属性的生成策略。
一个持久化对象对应数据库表中的一条记录,为了更好地持久化表中的每一条记录,需要通过<generator>元素的class属性设置采用的标识符属性生成策略,如下面的代码所示:1.<id name="id" type="ng.Integer" column="ID">2. <generator class="increment">3. </generator>4.</id><param>元素是<generator>元素的可选子元素,用来传递标识符属性生成时可能需要的一个或多个参数。
在Hibernate中内置了多种标识符属性生成策略,如果不能满足需要,还可以通过实现org.hibernate.id.IdentifierGenerator接口来定制标识符属性生成策略。
3.3.1 increment生成策略当Hibernate准备在数据库表中插入一条新记录时,首先从数据库表中获取当前主键字段的最大值,然后在最大值基础上加1,作为当前持久化对象的标识符属性值。
这种策略即i ncrement生成策略,用其生成的标识符属性的类型可以是long、short、i nt及其封装类的类型。
这种主键生成策略适合单服务器的Hibernate应用,同时数据库也只被这个Hibernate应用所独享;否则不能保证生成的标识符属性值的唯一性,即这种标识符属性生成策略并不适合非独享数据库或者分布式的Hibernate应用。
使用这种标识符属性生成策略的示例配置信息如下:1.<id name="id" type="ng.Integer" column="ID">2. <generator class="increment">3. </generator>4.</id>3.3.2 identity生成策略在MS SQL Server、MySQL和DB2等数据库中可以设置表中某一个字段的数值自动增长,identity生成策略通过这种方式为当前记录获取主键值的同时为持久化对象赋予标识符属性值。
该生成策略生成的标识符属性的类型可以是long、short、int及其封装类的类型。
使用这种标识符属性生成策略的示例配置信息如下:1.<id name="id" type="ng.Integer" column="ID">2. <generator class="identity">3. </generator>4.</id>3.3.3 sequence生成策略在Oracle、DB2和PostgreSQL等数据库中创建一个序列(sequence),然后Hibernate通过该序列为当前记录获取主键值,进而为持久化对象赋予标识符属性值。
此即sequence生成策略,用其生成的标识符属性的类型可以是long、short、int及其封装类的类型。
使用这种标识符属性生成策略的示例配置信息如下:1.<id name="id" type="ng.Integer" column="ID">2. <generator class="sequence">3. <param name="sequence">gb_seq</param>4. </generator>5.</id>第3行指定Hibernate使用的序列名,该行为可选。
如果未指定序列名,则Hibernate默认使用名为"hibernate_sequence"的序列。
3.3.4 hilo生成策略未hilo生成策略采用一种称为"高/低位"(hi/l o)的高效算法产生标识符属性值,所产生的标识符属性值为long、short、i nt及其封装类的类型。
该算法使用一个高位值(hi)和一个低位值(lo),然后计算其值,运算结果作为标识符属性值。
使用这种标识符属性生成策略需要在数据库中建立一个表和一个字段(默认表名为"hibernate_uni que_key",字段名为"next_hi",该字段要有数值)作为高位值的来源。
使用这种标识符属性生成策略的示例配置信息如下:1.<id name="id" type="ng.Integer" column="ID">2. <generator class="hilo">3. <param name="table">hibernate_key</param>4. <param name="column">next_hivalue</param>5. </generator>6.</id>这种标识符属性生成策略需要额外的数据库表和字段的支持,可保证为特定数据库生成唯一的标识符属性。
并且这种策略与底层使用的数据库无关,可以跨数据库使用。
3.3.5 seqhilo生成策略seqhilo生成策略也使用高/低位算法,产生的标识符属性值为long、short、int及其封装类的类型。
与hilo生成策略不同的是,它使用指定的sequence获取高位值。
使用这种标识符属性生成策略的示例配置信息如下:1.<id name="id" type="ng.Integer" column="ID">2. <generator class="seqhilo">3. <param name="sequence">hibernate_seq</param>4. </generator>5.</id>第3行指定Hibernate使用的序列名,该行为可选。
如果未指定序列名,则Hibernate默认使用名为"hi bernate_unique_sequence"的序列。
3.3.6 uuid生成策略uuid生成策略采用128位的UUID算法来生成一个字符串类型的主键值,这个算法使用IP地址、JVM的启动时间(精确到1/4秒)、系统时间和一个计数器值(在当前的JVM中唯一)经过计算来产生标识符属性值,可以用于分布式的Hibernate应用中。
产生的标识符属性是一个32位长度的字符串。
使用这种生成策略,对应持久化类中标识符属性的类型应该设置为String类型,其示例配置信息如下所示。
1.<id name="id" type="ng.String" column="ID">2. <generator class="uuid">3. </generator>4.</id>这种标识符属性生成策略生成的数值可以保证多个数据库之间的唯一性,由于该值是32位长的字符串,所以占用的数据库空间较大。
推荐在实际开发中使用这种生成策略。
3.3.7 guid生成策略这种标识符属性生成策略借助MS SQL Server或者MySQL数据库中的GUID字符串产生标识符属性值。