【Hibernate】--一对一关联、联合主键
一、数据模型
1.学生信息模型(编号、名称、身份信息)
public class Student implements java.io.Serializable{ private static final long serialVersionUID = 1L; private Integer sid; private String sname; private IdClass pid; public Integer getSid() { return sid; } public void setSid(Integer sid) { this.sid = sid; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public IdClass getPid() { return pid; } public void setPid(IdClass pid) { this.pid = pid; } }
2.身份信息模型(身份ID、省份)
public class IdClass implements java.io.Serializable{ private static final long serialVersionUID = 1L; private String pid; private String provience; private Student stu; public String getPid() { return pid; } public void setPid(String pid) { this.pid = pid; } public String getProvience() { return provience; } public void setProvience(String provience) { this.provience = provience; } public Student getStu() { return stu; } public void setStu(Student stu) { this.stu = stu; } }
二、单向唯一关联
A.配置文件描述
<hibernate-mapping package="com.hibernate.orm"> <class name="Student" table="student"> <id name="sid" type="java.lang.Integer" length="50"> <generator class="identity"/> </id> <property name="sname" column="s_name" not-null="false" type="java.lang.String"/> <!-- 主控方:这里虽然使用了many2one,但是设置了unique为true,这样就只能是单向一对一关联了 --> <many-to-one name="pid" column="pid" cascade="all" unique="true"/> </class> </hibernate-mapping>
<hibernate-mapping package="com.hibernate.orm"> <class name="IdClass" table="id_class_info"> <id name="pid" type="java.lang.String" length="20"> <generator class="assigned"/> </id> <property name="provience" column="provience" not-null="false" type="java.lang.String"/> <!-- 被控方:指定stu属性被IdClass中的pid属性控制 --> <one-to-one name="stu" property-ref="pid"/> </class> </hibernate-mapping>
B.注解描述(在相关的属性上添加注解描述)
@Entity @Table(name="student",catalog="study") public class Student implements java.io.Serializable{ private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Integer sid; @Column(name="s_name",nullable=false, length=11) private String sname; @OneToOne(cascade=CascadeType.ALL) @JoinColumn(name="pid", nullable=false, unique=true) private IdClass pid; //......getter和setter方法省略............ }
@Entity @Table(name="id_class_info",catalog="study") public class IdClass implements java.io.Serializable{ private static final long serialVersionUID = 1L; @Id @GeneratedValue(generator="pid") @GenericGenerator(name="pid",strategy="assigned") private String pid; @Column(name="provience", length=40, nullable=false) private String provience; //只要是双向关联就一定要指定mappedBy,将控制权交给指定的一方 @OneToOne(mappedBy="pid") private Student stu; //......getter和setter方法省略............ }
注:一对一关联配置参见网友博客:http://blog.csdn.net/dreamcatchergo/article/details/13627709
三、双向一对一外键关联
单向的基础上,添加另一方为被控方,通过one-to-one实现被控方描述
A.配置文件描述
<!-- 被控方:指定stu属性被IdClass中的pid属性控制 --> <one-to-one name="stu" property-ref="pid"/>
B.注解描述
//只要是双向关联就一定要指定mappedBy,将控制权交给指定的一方 @OneToOne(mappedBy="pid") private Student stu;
四、联合主键
添加主键类,在身份信息模型中添加血型,将身份ID和血型作为联合主键,代码如下
public class IdCardPK implements Serializable{ private static final long serialVersionUID = 1L; private String pid; private String bloodType; //血型 //******************* }
A.配置文件描述
<hibernate-mapping package="com.hibernate.orm.ufk"> <class name="IdClass" table="id_class_info"> <!-- 联合主键 --> <composite-id name="idCardPK" class="com.hibernate.orm.ufk.IdCardPK"> <key-property name="pid" column="p_id" length="20" type="string"/> <key-property name="bloodType" column="blood_type" length="10" type="string"/> <!-- 不能再指定 generator <generator class="assigned"/> --> </composite-id> <property name="provience" column="provience" not-null="false" type="string"/> </class> </hibernate-mapping>student方修改关联配置,将原有的pid做如下修改:
<many-to-one name="pid" cascade="all"> <column name="p_id" unique="true"/> <column name="blood_type"/> </many-to-one>
B.注解描述
主键类配置如下,注意添加getter和setter方法:@Embeddable public class IdCardPK implements Serializable{ private static final long serialVersionUID = 1L; @Column(name="p_id",nullable=false, length=20) private String pid; @Column(name="blood_type",nullable=false) private String bloodType; //血型 }身份信息修改如下
@EmbeddedId private IdCardPK idCardPK;学生信息模型关联身份信息配置:
@OneToOne(cascade=CascadeType.ALL) @JoinColumns({ @JoinColumn(name="p_id",referencedColumnName="p_id"), @JoinColumn(name="blood_type",referencedColumnName="blood_type") }) private IdClass pid;
五、组件关联(将POJO类中的属性作为添加到某实体类)
定义一个组件类POJO,代码如下:
public class IdClass{ private String provience; private String bloodType; public String getProvience() { return provience; } public void setProvience(String provience) { this.provience = provience; } public String getBloodType() { return bloodType; } public void setBloodType(String bloodType) { this.bloodType = bloodType; } }
A.配置文件描述
将POJO中的属性作为student的属性,配置如下:
<hibernate-mapping package="com.hibernate.orm.component"> <class name="Student" table="student"> <id name="sid" type="integer" length="50"> <generator class="identity"/> </id> <property name="sname" column="s_name" not-null="false" type="string"/> <!-- 组件关联配置 --> <component name="pid" class="IdClass"> <property name="provience" column="provience" length="20"/> <property name="bloodType" column="blood_type" length="10"></property> </component> </class> </hibernate-mapping>
B.注解描述,通过Embedded关联组件
//和组件关联 @Embedded private IdClass pid;