《Hibernate学习笔记三》:联合主键的映射
就如在前面所举的例子一样,是使用的id作为唯一的主键,一般情况下我们也只使用唯一的一个属性作为主键,但是在实际中,我们可能会遇到几个属性作为主键的情况,因此,在本篇博文中,就来介绍下,联合主键的映射关系应该如何来做??
联合主键的映射有两种方式来进行实现。
1、使用映射文件 XXX.hbm.xml
2、使用Annotation
Hibernate首先需要使用联合主键的实体类必须实现Serializable接口,即为了使序列能够被序列化进行传输,并要求实体类重写equals、hashCode这两个方法,用这两个方法来确保联合主键的唯一性。
下面具体来看一个例子。
先看第一种实现方式。
第一种:使用映射文件XXX.hbm.xml来实现联合主键的映射
a、实体类 Student
package com.hibernate.model;
public class Student {
private StudentPK pk;//主键
public StudentPK getPk() {
return pk;
}
public void setPk(StudentPK pk) {
this.pk = pk;
}
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
上面的private StudentPK pk;就是我们的联合主键,联合主键我们封装在了一个类StudentPK中,也可以之间将联合主键的属性不进行封装,直接写在实体类Student。
b、联合主键类 StudentPK
这个就是对联合主键id和name进行了封装,即使得StudentPK为联合主键类,这个类要实现Serializable接口,并需要重写equals和hashCode方法。来实现组合的标识符的相等判断
package com.hibernate.model;
import java.io.Serializable;
public class StudentPK implements Serializable{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o){
if (o instanceof StudentPK) {
StudentPK pk = (StudentPK) o;
if(this.id==pk.getId()&&this.name.equals(pk.getName())){
return true;
}
}
return false ;
}
@Override
public int hashCode(){
return this.name.hashCode();
}
}
c、联合主键的映射文件 Student.hbm.xml
在前面的例子中我们见到过一个属性作为主键的映射文件如何来写,下面就是几个属性作为主键的映射文件应该如何来写。
在官方文档上有这样一句话:
定义可以访问旧式的多主键数据。 我们强烈不建议使用这种方式。
文档上面给出的composite-id的一般格式如下:
<composite-id
name="propertyName"
class="ClassName"
mapped="true|false"
access="field|property|ClassName"
node="element-name|."
>
<key-property name="propertyName" type="typename" column="column_name"/>
<key-many-to-one name="propertyName class="ClassName" column="column_name"/>
......
</composite-id>
在我们的例子中完整的映射文件内容如下:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.model">
<class name="Student" table="Student"> <!-- 如果我们不写table,则默认表名与类名一致 -->
<!-- 联合主键 -->
<composite-id name="pk" class="com.hibernate.model.StudentPK"></