技术分享 HIBERNATE 查看内容

映射Hibernate对象标识符

老高 | 发布于 2016-04-04 21:29| 浏览()| 评论() | 收藏() | 点赞() | 打印

摘要: Hibernate中的持久化对象对应数据库中的一张数据表,因此区分不同的持久化对象就不能像以往的JAVA方法通过Object对象的默认equals()方法进行,在Hibernate中是通过OID来完成的,OID对应数据库中的主键。

Hibernate中的持久化对象对应数据库中的一张数据表,因此区分不同的持久化对象就不能像以往的JAVA方法通过Object对象的默认equals()方法进行,在Hibernate中是通过OID来完成的,OID对应数据库中的主键。

接下来我将讲解Hibernate中的主要对象标识生成方法,在Hibernate中共有8种标识符生成方式,其中包括7种标识符生成器和一种复合主键生成方式。

(1)increment标识符生成器:

配置方式:

<hibernate-mapping>
<class name="IncrementTester" table="INCREMENT_TESTER">
    <id name="id"type="long"column="ID">
        <generator class="increment"/>
    </id>
</class>
</hibernate-mapping>

使用这种方式生成OID,Hibernate汇在持久化一个对象时以递增的方式产生OID,此方式不依赖于底层数据库,并且只适用于但进程环境下,在多线程环境下很可能生成相同主键值,而且OID必须为long,int,short类型。

(2)identify标识符生成器:

配置方式:

<hibernate-mapping>
<classname="IdentifyTester" table="IIDENTIFY_TESTER">
    <id name="id"type="long" column="ID">
        <generator class="identify"/>
    </id>
</class>
</hibernate-mapping>

identify生成标识符的机制依赖底层数据库的支持,因此,要求底层数据库系统必须支持自动增长字段类型,而且OID必须为long,int,short类型。

(3)sequence标识符生成器:

配置方式:

<hibernate-mapping>
。。。。
    <id name="id" type="long" column="ID">
        <generator class="sequence">
            <param name="sequence">tester_id_seq</param>
        </generator>
    </id>
。。。。
</hibernate-mapping>

由sequence生成标识符的机制依赖于底层数据库系统的序列,因此,需要数据库支持序列机制(如:oracle等),而且OID必须为long,int,short类型。

(4)hilo标识符生成器:

配置方法:

<hibernate-mapping>
。。。。
<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>
。。。。
</hibernate-mapping>

hilo标识符生成器由Hibernate按照一种high/low算法生成标识符,他从数据库中的特定表的字段中获取high值,因此需要额外的数据库表保存主键生成的历史状态,hilo生成方法不依赖于底层数据库,因此适用于每一种数据库,但是OID必须为long,int,short类型。

(5)native标识符生成器:

配置方法:

<hibernate-mapping>
。。。。
<id name="id" type="long" column="ID">
    <generator class="native"/>
</id>
。。。。
</hibernate-mapping>

native生成器能根据底层数据库系统的类型,自动选择合适的标识符生成器,因此非常适用于跨数据库平台开发,他会由Hibernate根据数据库适配器中的定义,自动采用identify,hilo,sequence的其中一种作为主键生成方式,但是OID必须为long,int,short类型。

(6)uuid.sex标识符生成器:

配置方法:

<hibernate-mapping>
。。。。
<id name="id" type="long" column="ID">
    <generator class="uuid.sex"/>
</id>
。。。。
</hibernate-mapping>

由Hibernate基于128位唯一值产生算法,根据当前设备IP,时间,JVM启动时间,内部自增量等4个参数生成16进制数值作为主键,一般而言,利用uuid.sex方式生成的主键提供最好的数据插入性能和数据库平台适应性。

(7)assign标识符生成器:

<hibernate-mapping>
。。。。
<id name="id" type="long" column="ID">
    <generator class="assign"/>
</id>
。。。。
</hibernate-mapping>

采用assign生成策略表示由应用程序逻辑来负责生成主键标识符。

(8)映射复合主键

第一种方式由是实体类中的属性组成,实体类本身即同时扮演复合主键类的角色。

配置方式:

<hibernate-mapping>
<class name="Customer" table="CUSTOMER">
<composite-id>
    <key-property name="name" column="NAME" type="string"/>
    <key-property name="compayid" column="COMPANYID" type="string"/>
</composite-id>
</class>
</hibernate-mapping>

此时若想使用session.load()方法加载该实体,要求该实体必须实现java.io.Serializable接口,并且要提供equals()方法和hashCode()方法的实现。

例:

public class Customer implements Serilizable{
private final String name;
private final String companyId;
…….
public boolean equals(Objecto){
    if(this==o) return false;
    if(!(o instanceof Customer))return false;
    Customer other=(Customer)o;
    if(!name.equals(other.getName()))return false;
    if(!companyId.equals(other.getCompanyId()))return false;
    return true;
}
public int hashCode(){
    int result = (name==null)?0:name.hasCode();
    result = 29*result+(companyId==null?0:companyId.hasCode());
    return result;
}
}
Customer c = new Customer();
c.setName(“zx");
c.setCompanyId(“Neusoft");
session.load(Customer.class,c);


第二种方式:以独立主键类映射复合主键,这样可以达到将逐渐逻辑加以隔离的目的。

配置方式:

<hibernate-mapping>
<class name="Customer" table="CUSTOMER">
<composite-id name="customerId" class="mypack.CustomerId">
    <key-property name="name" column="NAME" type="string"/>
    <key-property name="compayid" column="COMPANYID" type="string"/>
</composite-id>
</class>
</hibernate-mapping>

主键类:

public class CustomerId{
private String name;
private String customerId;
…….
}

实体类:

public class Customer{
private CustomerId cid;
private String address;
……..
}
CustomerId customerid=new CustomerId();
Customerid.setName(“zx");
Customerid.setSustomerId(“Neusoft");
Customerc=(Customer)session.load(Customer.class,customerid);

发表评论(对文章涉及的知识点还有疑问,可以在这里留言,老高看到后会及时回复的。)

表情