Hibernate笔记4--component和联合主键

来源:互联网 发布:mac windows系统截屏 编辑:程序博客网 时间:2024/06/05 15:59
引用属性的意思是:持久化类的属性既不是基本数据类型,也不是String 字符串,
而是某个引用变量,该引用属性的类型可以是自定义类。

例如Person类里有这么一条属性:private Name name;

此时Person 的name 属性既不是基本数据类型,也不是String,而是一个自定义类:Name.

此时我们将采用如下的配置方式:

<component name="name" class="Name" unique="true">
    <property name="first"/>
    <property name="last"/>
</component>

注意:Name类里的两个属性:first,last。unique="true"并不是必须的,根据业务需求。

----------------------------------------------------------------------------------------------------

事实上,在更多情况下,集合里存放的都是引用类型,看下面POJO 的源代码:

Person 类有一条属性:private List schools = new ArrayList();

而School类则一共有两个属性:name, address;

如果集合里的元素是普通宇符串,则使用element 映射集合元素即可。如果集合元素是自定义类,则须使用composite-element 子元素来映射集合元素。参考Hibenate笔记1和2.

<list name="schools" table="school">
     <key column="personid" not-null="true"l>
     <list-index column="list_order"l>
     <composite-element class="School">
           <property name="name"l>
           <property name="address"l>
     </composite-element>
</list>

一种特殊情况:当引用类型刚好为主键

这个时候的映射该如何写?

在数据库中建模时,尽量不要使用复杂的物理主键,应考虑为数据库增加一列,作为逻辑主键

使用物理主键还会增加数据库维护的复杂度,因为主从表之间的约束关系隐讳难懂,难于维护。

如果数据库采用简单的逻辑主键,则不会出现引用类型主键。

例如Person class,中的主键private Name name;

Name class 的两个属性firstName,lastName;

如果持久化类需要使用引用类型作为表示属性时,则该类应该满足如下两个条件:
.实现java.io.Seria1izable 接口。
·重写equals()和hashCode()方法,这两个方法的返回值都应该根据数据表中联合主
键的列来判断。

public class Name implements Serializable
private String firstName;
private String lastName;
public Name(){}
public Name(String sl , String s2)
{
this.firstName = sl;
this.lastName = s2;

……

public int hashcode(){

return firstName.hashcode() + lastName.hashCode();

}

public boolean equals(Object o){

if(o instanceof Name){

Name n = (Name)o;

if(n.firstName.equals(firstName)&&n.lastName.equals(lastName)){

return true;}else{return false;}

}else {return false;}

}

显然,例子中的联合主键是lastName和firstName;而为什么要重写equals() ,hashcode()方法呢,

hashcode一般用于查询,而equals则用于比较。具体我会找找资料。搞清楚。

引用类型主键的映射时,应使用composite-id元素,该元素需要class 属性来确定主
键的引用类型,并使用key-property元素来确定引用类型包含的基本属性。

<hibernate-mapping package="lee">
<class name="Person" table="person">
<composite-id name="name" class="Name">
<key-property name="firstName"/>
<key-property name="lastName"/>
</composite-id>
<property name="age"/>
</class>
</hibernate-mapping>

---------------------------------------------------------------------------------------------

另外一种情况是这样的,这相对比上面这种要常见一点

改写上面的持久化类Person,不使用name 作为Person 的标识属性,而是直接使用
firstName 和lastName 作为标识属性。

Person 类

private String lastname;

private String firstname;

当然也要实现Serializable接口和重写equals 和hashCode方法。

他的配置xml 是这样写的

<hibernate-mapping package="lee">
<class name="Person" table="personcomid">
<composite-id>
<key-property name="firstname"/>
<key-property name="lastname"/>
</composite-id>
<property name="age"/>
</class>
</hibernate-mapping>

由此可看出,这两种映射方式的效果差不多,其映射出来的表结构也基本一