例如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>
由此可看出,这两种映射方式的效果差不多,其映射出来的表结构也基本一