主键关联
两个关联的实体在表中具有相同的主键值,这个主键可只由其中一个表生成,在另外一个表中通过映射文件中使用主键的foreign生成机制引用已经生成的主键值。
Student类
package Mapping2;
public class Student {
private Long id;
private long studentNo;
private String studentName;
private int sage;
private String major;
/* 进行一对一关联,双方互添引用对方对象的属性及方法 */
private Card card;
public Card getCard() {
return card;
}
public void setCard(Card card) {
this.card = card;
}
public Student() {}
public Student(long studentNo, String studentName, int sage, String major) {
super();
this.studentNo = studentNo;
this.studentName = studentName;
this.sage = sage;
this.major = major;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public long getStudentNo() {
return studentNo;
}
public void setStudentNo(long studentNo) {
this.studentNo = studentNo;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public int getSage() {
return sage;
}
public void setSage(int sage) {
this.sage = sage;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
}
Student.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="Mapping2">
<class name="Student" table="student" >
<id name="id" column="id">
<generator class="identity"/>
</id>
<property name="studentNo" type="long" column="student_no"/>
<property name="studentName" type="string" column="student_name"/>
<property name="sage" type="integer" column="sage"/>
<property name="major" type="string" column="major"/>
<one-to-one name="card" class="Mapping2.Card" cascade="all" fetch="join" />
</class>
</hibernate-mapping>
package Mapping2;
public class Card {
private Long id;
private String cardNo;
private String major;
private double balance;
/* 一对一关联,双方互添引用对方对象的属性及方法 */
private Student student;
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public Card() {
// TODO Auto-generated constructor stub
}
public Card(String cardNo, String major, double balance) {
this.cardNo = cardNo;
this.major = major;
this.balance = balance;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCardNo() {
return cardNo;
}
public void setCardNo(String cardNo) {
this.cardNo = cardNo;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
}
Card.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="Mapping2">
<class name="Card" table="card" lazy="true" >
<id name="id" column="id">
<generator class="foreign"> <!-- 一对一关系映射,主键关联class是 foreign,外键关联是identity -->
<param name="property">student</param>
</generator>
</id>
<property name="CardNo" type="string" column="CardNo"/>
<property name="major" type="string" column="major"/>
<property name="balance" type="double" column="balance"/>
<!-- 一对一主键关联 -->
<one-to-one name="student" class="Mapping2.Student" constrained="true" />
</class>
</hibernate-mapping>
测试
package Mapping2;
import org.hibernate.Transaction;
import org.hibernate.Session;
import util.HibernateUtil;
public class OneToOnePrimaryKeyAssociation {
public static void main(String[] args) {
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
Student student = new Student(20120101,"Akbar Housein",20,"电子商务");
Card card = new Card("110101","电子商务",1500.00);
student.setCard(card);
card.setStudent(student);
session.save(student);
tx.commit();
}
}
结果
外键关联
一对一的外键关联是指两个实体各自有自己的主键,但其中一个实体用外键引用另外一个实体。例如,Student实体和Card实体各自对应表的主键都是id,设在card表中还有一个studentId属性,它引用student表的id列,在card表中studentId就是外键。
若仍建立双向关联,则Student.hbm.xml无须修改,修改后的Card.hbm.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="Mapping2">
<class name="Card" table="card" lazy="true" >
<id name="id" column="id">
<generator class="identity"> <!-- 一对一关系映射,主键关联class是 foreign,外键关联是identity -->
<param name="property">student</param>
</generator>
</id>
<property name="CardNo" type="string" column="CardNo"/>
<property name="major" type="string" column="major"/>
<property name="balance" type="double" column="balance"/>
<!-- 一对一主键关联
<one-to-one name="student" class="Mapping2.Student" constrained="true" />-->
<!-- 一对一外键关联 -->
<many-to-one name="student" class="Mapping2.Student"
column="studentId" unique="true" />
<!-- 一对一关联实际是多对一关联的特例,当将<many-to-one>元素的unique属性值指定为true时,
多对一的关联实际上变成了一对一的关联 -->
</class>
</hibernate-mapping>
上面Card类的基础上再加入studentId属性及setter、getter方法和新构造函数
/*一对一外键关联 */
private Student studentId;
public Student getStudentId() {
return studentId;
}
public void setStudentId(Student studentId) {
this.studentId = studentId;
}
public Card(String cardNo, String major, double balance,
Student studentId) {
this.cardNo = cardNo;
this.major = major;
this.balance = balance;
this.studentId = studentId;
}
将上面测试类中
Card card = new Card("110101","电子商务",1500.00);
改为
Card card = new Card("110101","电子商务",1500.00,student);
运行结果