Hibernate映射对象标识符

1.关系数据库按主键区分不同的记录

1.1.把主键定义为自动增长标识符类型

eg . MySql中,把表的主键设为auto_increment类型:

create table CUSTOMERS(ID int auto_increment primary key not null,NAME varchar(15))

MS SQL Server中,把表的主键设为identity类型:

create table CUSTOMERS(ID int identity(1,1) primary key not null,NAME varchar(15))

1.2.从序列(Sequence)中获取自动增长的标识符

eg. Oracle数据库中,为表的主键创建一个单独的序列,从序列中获得自动增长的标识符,赋值给主键:

create sequence CUSTOMER_ID_SEQ increment by 1 start with 1;

create table CUSTOMERS(ID int primary key not null,NAME varchar(15));

insert into CUSTOMERS valus(CUSTOMER_ID_SEQ.curval,'Tom');

insert into CUSTOMERS valus(CUSTOMER_ID_SEQ.nextval,'Mike');


2.Java按内存地址区分不同的对象

"=="运算符就是比较的内存地址,在Object类中定义的equals(Object o)方法,也是按内存地址进行比较的。

Java API中的一些类覆盖了Object;类的equals(Object o)方法,实现按值比较,这些类包括:String类和Date类;Java包装类:Byte、Integer、Short、Character、Long、Float、Double和Boolean。

3.Hibernate用对象标识符(OID)来区分对象

OID是关系数据库的主键在Java对象模型中的等价物。

在对象-关系映射文件中,<id>元素用来设置对象标识符,<generator>子元素用来设定标识符生成器:

<id name="id" type="long" column="ID">

    <generator class="increment" />

</id>


Hibernate提供的内置标识符生成器:

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

identity:适用于代理主键。由底层数据库生成标识符,前提条件是递增数据库支持自动增长字段类型,如DB2、MySQL、MS SQL Server、Sybase和HypersonicSQL。

sequence:适用于代理主键。Hibernate根据底层数据库的序列来生成标识符,前提条件是底层数据库支持序列,如DB2、PostgreSQL、Oracle和SAP DB。

hilo:适用于代理主键。Hibernate根据high/low算法来生成标识符,Hibernate把特定表的字段作为"high"值,在默认情况下选用hibernate_unique_key表的next_hi字段。

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

uuid.hex:适用于代理主键。Hibernate采用128位的UUID(Universal Unique Identification)算法来生成标识符。UUID算法能够在网络环境中生成唯一的字符串标识符。

assigned:适用于自然主键。由Java应用程序辅助生成标识符,为了能让Java应用程序设置OID,不能把setID()声明为private类型。

select:适用于遗留数据库中的代理主键或自然主键。由数据库中的触发器来生成标识符。

foreign:用另一个关联的对象的标识符来作为当前对象的标识符,主要适用于一对一关联的场合。

4.Hibernate内置标识符生成器的用法

4.1.increment

不依赖底层数据库系统,适用于所有的数据库系统。

适用于只有单个Hibernate应用进程访问用一个数据库的场合,集群环境下不推荐使用。

<id name="id" type="long" column="ID">

    <generator class="increment" />

</id>

4.2.identity

要求底层数据库必须支持自动增长类型。OID必须为long、int或short类型。

<id name="id" type="long" column="ID">

    <generator class="identity" />

</id>


MySQL:

create table CUSTOMERS(ID bigint auto_increment primary key not null);

MS SQL Server:

create table CUSTOMERS(ID bigint identity primary key not null);

4.3.sequence

要求底层数据库必须支持序列。OID必须为long、int或short类型。

<id name="id" type="long" column="ID">

    <generator class="sequence">

        <param name="sequence">CUSTOMER_ID_SEQ</param>

    </generator>

</id>

Oracle:

create sequence CUSTOMER_ID_SEQ;

create table CUSTOMERS(ID bigint primary key not null);

4.4.hilo

不依赖底层数据库系统,适用于所有的数据库系统。OID必须为long、int或short类型。

high/low算法生成的标识符只能在一个数据中保持唯一。

当用户为Hibernate自行提供数据库连接,或HIbernate通过JTA从应用服务器的数据源获得数据库连接时无法使用hilo。

<id name="id" type="long" column="ID">

    <generator class="hilo">

        <param name="table">hi_value</param>

        <param name="column">next_value</param>

        <param name="max_lo">100</param>

    </generator>

</id>


create table CUSTOMERS(ID bigint primary key not null);

create table hi_value(next_value integer);


4.5.native

能够根据底层数据库系统的类型,自动选择合适的标识符生成器,很适合于跨数据平台开发。

OID必须为long、int或short类型。

<id name="id" type="long" column="ID">

    <generator class="native" />

</id>


MySQL:

create table CUSTOMERS(ID bigint auto_increment primary key not null);


MS SQL Server:

create table CUSTOMERS(ID bigint identity primary key not null);

5.映射自然主键

5.1.映射单个自然主键

eg. CUSTOMERS表中没有定义ID代理主键,而是以NAME字段作为主键,则在Customer类中不必定义id属性,Customer的OID为name属性,映射文件为:

<id name="name" column="NAME" type="string">

     <generator class="assigmed" />

</id>

...

<version name="version" column="VERSION" unsaved-value="null" />

5.2.映射符合自然主键

eg. CUSTOMERS表中没有定义ID代理主键,而是以NAME字段和COMPANY_ID字段作为复合主键,则在Customer类中不必定义id属性,Customer的OID为name属性和companyId属性,映射文件为:

<composite-id>

    <key-property name="name" column="NAME" type="string" />

    <kry-property name="companyId" column="COMPANY_ID" type="long" />

</composite-id>

...

<version name="version" column="VERSION" unsaved-value="null" />


另一种方式是定义单独的主键类:

CustomerId.java:

public class CustomerId implements Serializable{

    private final String name;

    private final Long companyId;

    Constructor...;getter...;setter...;

    public boolean equals(Object o){...}

    public int hashCode(){...}

}


在Customer类中,不必定义name和companyId属性,而是定义customerId属性:

private CustomerId customerId;

映射文件:

<class name="mypack.Customer" table="CUSTOMERS">

    <composite-id name="customerId" class="mypack.CustomerId">

        <key-property name="name" column="NAME" type="string" />

        <kry-property name="companyId" column="COMPANY_ID" type="long" />

    </composite-id>

    ...

    <version name="version" column="VERSION" unsaved-value="null" />
</class>


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值