hibernate映射对象标识符

(一)、标示符的概念

Java按内存地址区分同一个类的不同对象,关系数据库用主键区分同一个表的不同记录,Hibernate使用OID(对象标识符)来建立内存中的对象和数据库中记录的对应关系。

    对象的OID和数据库表的主键对应。为保证OID的唯一性和不可变性,应该让Hibernate而不是应用程序来为OID赋值。


(二)、关系数据库按主键区分不同记录

主键必备条件:

1、不允许null

2、唯一,不重复

3、值永远不会改变

  •     自然主键:把具有业务含义的字段作为主键叫做自然主键。
  •     代理主键:不具有业务含义,推荐使用。

(三)、hibernate的对象标示符

OID是关系数据库中的主键在java对象模型中的等价物。在运行时,hibernate根据OID来维持java对象和数据库记录的对应关系。

Customer c1 = (Customer)session.get(Customer.class,newLong(1));
Customer c2 = (Customer)session.get(Customer.class,newLong(1));
Customer c3 = (Customer)session.get(Customer.class,newLong(3));
c1 == c2 ?
c1 == c3 ?

1、对象标示符的类型:


标识符生成器

描述

Increment

适用于代理主键。由hibernate自动以递增的方式生成标识符,每次增量为1

Identity

适用于代理主键。由底层数据库生成标识符。条件是数据库支持自动增长数据类型。

Sequence

适用于代理主键。Hibernate根据底层数据库序列生成标识符。条件是数据库支持序列。

Hilo

适用于代理主键。Hibernate根据hign/low算法生成标识符。Hibernate把特定表的字段作为“hign”值。默认情况下,采用hibernate_unique_key表的next_hi字段。

Native

适用于代理主键。根据底层数据库对自动生成标识符的能力来选择identity、sequence、hilo

Uuid.hex

适用于代理主键。Hibernate采用128位的UUID算法来生成标识符。该算法能够在网络环境中生成唯一的字符串标识符,这种策略并不流行,因为字符串类型的主键比整数类型的主键占用更多的数据库空间。

assigned

适用于自然主键。由java程序负责生成标识符。不能把setID()方法声明为

Private的。尽量避免使用自然主键。


2、Hibernate内置标识符用法

(1)、Increment

使用increment方式时,hibernate将按照递增的方式设定主键,具体的方式是,先获取当前记录主键的最大值,然后再将该值加1作为主键。

selectmax(id) from table;

<idname=“id” type=“long” column=“ID”>      <generator class=“increment”/></id>

适用范围:

1。由于不依赖与底层数据库,适合所有的数据库系统。

2。单个进程访问同一个数据库的场合,集群环境下不推荐适用。

3。OID必须为long、int或short类型,如果把OID定义为byte类型,抛异常。


(2)、Identity

identity方式表示数据库的主键生成方式为采用数据库的主键生成机制,例如SQLServer或MySQL的自动主键生成机制。

  由底层数据库生成标识符.需要把字段定义成自增型。

  my sql 中为auto_increment

  ms sql server中为identity


使用mysql

<generatorclass="identity">
           <param name="identity">auto_increment</param>
      </generator>

mysql表:

createtable CUSTOMER(
     ID int NOT NULL auto_incrementprimary key,
     NAME varchar(15)not null,
     EMAIL varchar(128)not null
);

(3)Sequence

这种方式针对由序列方式产生主键的数据库,例如Oracle。在<generator>的子元素<param name=“sequence”>指定用作产生主键的序列名称。

<id name=“id” type=“long” column=“ID”>
      <generator class=“sequence”>
              <param name=“sequence”>tester_id_seq</param>
      </generator>
</id>

适用范围:

底层数据库要支持序列。OracleDB2 SAP等。

OID必须为long、int或shot类型,如果把OID定义为byte类型,运行时抛异常。

(4)Hilo

Hilo标识符生成器由Hibernate按照一种hign/low算法来生成标识符,它从数据库的特定表的字段中获取high值。

<id name=“id” type=“long” column=“ID”>
     <generator name=“hilo”>
             <param name=“table”>hi_value</param>
             <param name=“column”>next_value</param>
             <param name=“max_lo”>100</param>
     </generator>
</id>

使用范围:

该机制不依赖于底层数据库,因此适用于所有的数据库系统。

OID必须为long、int、short类型,如果为byte类型的话,会抛出异常。

org.hibernate.id.IdentifierGeneratorException:this idgenerator generates

Long、integer、short。


(5)Native

native方式意味着将主键的生成机制交由Hibernate决定,Hibernate会根据配置文件中的方言(Dialect)定义,采用不同

的数据库特定的主键生成方式。

<id name=“id” type=“native” column=“ID”>
      <generator class=“native” />
</id>


适用范围:

该类型能根据底层数据库系统的类型,自动选择合适的标识符生成器,因此很适合于跨数据

库的平台,即在同一个应用中需要连接多种数据库系统的场合。

OID必须为long、int、short类型,如果为byte类型的话,会抛出异常。

Org.hibernate.id.IdentifierGeneratorException:this idgenerator generates

Long、integer、short。


(6)assinged:

assinged方式意味着将主键的生成机制交由应用程序自己控制。只需要在持久化之前传入对象主键值即可。

<id name=“id” column=“ID”>
      <generator class=“assinged” />
</id>
(7) hibernate 增强的标识符生成器

org.hibernate.id.enhanced.TableGenerator

table_name(可选— 默认是 hibernate_sequences):所用的表的名称

value_column_name(可选— 默认为 next_val):用于存储这些值的表的字段的名字

segment_column_name(可选,默认为sequence_name):用于保存 "segment key" 的字段的名

segment_value(可选,默认为default):我们为这个生成器获取增量值的 segment 的

"segmentkey"

initial_value(可选— 默认是 1):从表里获取的初始值

increment_size(可选— 默认是 1):对表随后的调用应该区分的值


<id name="id" type="long" column="id">
	<generator class="org.hibernate.id.enhanced.TableGenerator">
		<param name="segment_value">customer</param>
	</generator>
</id>

3、映射符合主键

(1)在实体类中直接映射符合主键(embeded)

<composite-id>
<key-propertyname="name"/>
<key-propertyname="email"/>
</composite-id>

(2)使用独立的标识类(mapped),复合主键在标识类和实体类中都存在

<composite-idclass="CompositeId"mapped="true">
<key-propertyname="name"/>
<key-propertyname="email"/>
</composite-id>

(3)使用独立的标识类(mapped),复合主键在标识类中存在

<composite-idclass="CompositeId" name="id" mapped="false">
  <key-property name="name" />
  <key-property name="email" />
</composite-id>

注意:标识类必须实现Serializable接口,最好实现equals方法和hashcode方法; 必须初始化持久化类的实例,填充它的标识符属性,再 load()组合关键字关联的持久状态。这种方法称为 embedded(嵌入式)的组合标识符.

Session session = HibernateUtil.getSession();
Customer cus1 = new Customer();
cus1.setEmail("itcast@126.com");
session.load(Customer.class, cus1);
Customercus2=(Customer)session.get(Customer.class,cus1);



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值