hibernate中一对一关系看起来简单,其实也挺复杂的。其中关系就包含了四种,单向双向和主键关联外键关联。 什么意思呢,也就是包含了单向一对一主键关联、双向一对一主键关联,单向一对一外键关联.
因为一对一的主键关联映射扩展性不好,当我们的需要发生改变想要将其变为一对多的时候变无法操作了,所以我们遇到一对一关联的时候经常会采用唯一外键关联来解决问题,而很少使用一对一主键关联。
所以现在就说一下基于外键的双向一对一.一对一其实是多对一的一种特殊形式,就是在多的一段加入unique=”true”属性,这样就限制了多的一端的多重性变为唯一.
一.思路分析
人和身份证信息是一对一的.双向就是既可以根据Person找到对应的Card;也可以通过Card找到相应的Person.
如图所示:
二.实体类的编写
Person.java
public class Person {
private Integer personId;
private String personName;
private Card card;
(以及相应的set . get方法)
}
Card.java
public class Card {
private Integer cardId;
private Integer cardNum;
private Person person;
(以及相应的get .set方法)
}
三.映射文件(*.hbm.xml)
Person.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="com.qiushiju.model">
<class name="Person" table="person">
<id name="personId" column="person_id">
<generator class="native" />
</id>
<property name="personName" column="person_name" />
<!-- 虽然是一对一,但是这里用了many-to-one,但是指定多的一端的unique=true,这样就限制了多端的多重性为一
name:对前持久化类中的所关联对象的属性
column:当前持久化类中的所关联对象在本表(person)的外键(即关联表(card)的主键) -->
<many-to-one name="card" column="card_id" unique="true"></many-to-one>
</class>
</hibernate-mapping>
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="com.qiushiju.model">
<class name="Card" table="card">
<id name="cardId" column="card_id">
<generator class="native" />
</id>
<property name="cardNum" column="card_num" />
<!-- 一对一标签,
name:当前持久化类所关联对象的属性
property-ref:这是必须的属性,是指定所关联类(Person)中的相对应的属性名
-->
<one-to-one name="person" property-ref="card"></one-to-one>
</class>
</hibernate-mapping>
四.把映射文件注入配置文件中hibernate.cfg.xml
<mapping resource="Person.hbm.xml" />
<mapping resource="Card.hbm.xml" />
五.测试
添加.测试添加一个人,和相应的id
public class TestOneToOne {
public static void main(String[] args) {
//读取cfg.xml文件
Configuration configuration = new Configuration().configure();
//建立sessionFactory
SessionFactory factory = configuration.buildSessionFactory();
//取得session
Session session = factory.openSession();
session.beginTransaction();
//创建人物
Person person = new Person();
person.setPersonName("赵雪丽");
//创建Card
Card card = new Card();
card.setCardNum(987654321);
//设置关联
person.setCard(card);
//保存
// ① session.save(card);
session.save(person);
session.getTransaction().commit();
注意上面①处,如上面的两个映射文件的配置的话,注释需要打开(即同时保存两个)才能同时保存成功.
但是在Person.hbm.xml中的下面代码中加入级联属性cascade为all或者save-update就可注释掉①处,只保存一个对象,就可以同时保存两张表的数据
<many-to-one name="card" column="card_id" unique="true" cascade="all"></many-to-one>
测试结果:
(第一行数据是本人自己测试时添加的)
双向查询测试
//通过Person对象找Card
Person p1 = (Person) session.get(Person.class, 1);
System.out.println("--->"+p1.getCard().getCardNum());
//通过Card对象找Person
Card card = (Card) session.get(Card.class, 1);
System.out.println("--->"+card.getPerson().getPersonName());
输出结果:
—>123456789
—>邱世举
参考文章:
http://blog.csdn.net/huangaigang6688/article/details/7761310#comments
http://www.cnblogs.com/whgk/p/6128395.html
http://blog.csdn.net/lm709409753/article/details/51038889#comments