叶凡网络:精通Hibernate:映射对象标识符

2013-12-25 10:30:02 | 新闻来源:叶凡网络 | 点击量:582

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

 

自然主键(具有业务含义的字段),如用户自定义的NAME;而代理主键不具备业务含义的字段,该字段一般取名为“ID”。

 

在java语言中,“==”判断的是引用,“equals”判断的是值。因此,

 

 

 

 

 

一、代理主键的映射

 

为了保证持久化对象的OID的唯一性和不变性,通常有Hibernate或底层数据库来给OID复制。因此,可以把持久化类的OID的setId()方法设置为Private类型以禁止Java应用程序随便修改OID;而把getId()方法设为public类型,使得Java应用程序都可以读取持久化对象。

 

在对象关系映射文件中,<id>元素用来设置对象标识符,例如:

 

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

     <generator class="increment"/>  

</id> 

 

 

二、自然主键的映射

 

自然主键是具有业务含义的主键。应尽量避免使用自然主键。

 

映射单个自然主键name

 

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

<generator class="assigned"/>  

</id> 

在以上代码中,标识符生成策略为“assigned”,表示有应用程序为name属性赋值。

 

可以使用

 

Customer customer=new Customer();  

session.getIdentifier(customer); 

来返回Customer的OID,以上返回的是Customer对象的name属性。

 

映射复合自然主键:

 

<composite-id>  

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

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

</composite-id> 

Customer customer=new Customer();  

customer.setName("Tom");  

customer.setCompanyId(new Long(11));  

session.saveORupadate(customer);//保存和更新指定记录  

session.get(Customer.class,customer);//获取NAME字段为Tom并且COMPANY_ID字段为11的记录 

映射复合自然主键的另一种方式为先定义单独的主键类。如下:

 

package mypack;  

public class CustomerId  implements java.io.Serializable {  

     private String name;  

     private Company company;  

 

    public CustomerId() {  

    }  

 

    public CustomerId(String name, Company company) {  

       this.name = name;  

       this.company = company;  

    }  

 

    public String getName() {  

        return this.name;  

    }  

 

    public void setName(String name) {  

        this.name = name;  

    }  

    public Company getCompany() {  

        return this.company;  

    }  

 

    public void setCompany(Company company) {  

        this.company = company;  

    }  

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

 

映射代码如下:

 

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

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

      <key-property name="companyId" column="COMPANY_ID" type="long"> </composite-id> 

三、自然主键(存在外键)的映射

 

假设上例中COMPANY_ID还作为外键参照COMPANYS表,那么Customer类中除了定义customerId属性,还必须定义company属性:

 

private CustomerId customerId;  

private Company company; 

映射company属性的代码:

 

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

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

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

</composite-id>  

<many-to-one name="company" class="mypack.Company" column="COMPANY_ID" insert="false" update="false"/> 

以上<many-to-one>元素的insert和update属性都是false,表明当Hibernate保存或者更新Customer对象时,会忽略company属性。

 

也可以用<key-many-to-one>元素来映射company属性:

 

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

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

    <key-many-to-one name="company" class="mypack.Company" column="COMPANY_ID" />  

  </composite-id> 

上一篇:叶凡网络:10分钟用Play!在GAE上实现一个Blog 下一篇:叶凡网络:中央农村工作会议:把“三农”工作紧紧抓好