一对一关联表示两个对象之间是一对一的关系,如Person-IdCard。有两种策略可以实现一对一的关联映射:
Ø 主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系;数据库表不会有额外的字段来维护它们之间的关系,仅通过表的主键来关联;
Ø 唯一外键关联:外键关联,本来是用于多对一的配置,但是如果加上唯一的限制之后,也可以用来表示一对一关联关系;
一对一主键关联映射:让两个实体对象的id保持相同,这样可以避免多余的字段被创建。
具体映射:
<id name="id">
<!-- person的主键来源idCard,也就是共享idCard的主键 -->
<generator class="foreign">
<param name="property">idCard</param>
</generator>
</id>
<property name="name"/>
<!-- one-to-one标签的含义,指示hibernate怎么加载它的关联对象,默认根据主键加载,
constrained="true", 表明当前主键上存在一个约束,person的主键作为外键参照了idCard
-->
<one-to-one name="idCard" constrained="true"/>
步骤:
n 建立POJO类:IdCard.java和Person.java, 建立Hibernate配置文件,将两个hbm文件与其绑定。
n 在Person.java里面建立一个IdCard类型的属性
n 在Person的hbm文件中添加:
<one-to-one name="idCard" constrained="true"/> |
n 代码实现:
IdCard.java
public class IdCard { private int id; private String cardNo; |
Person.java
public class Person { private int id; private String name; private IdCard idCard; |
IdCard.hbm.xml
<hibernate-mapping> <class name="IdCard" table="t_idcard"> <id name="id"> <generator class="native"/> </id> <property name="cardNo"/> </class> </hibernate-mapping> |
Person.hbm.xml
<hibernate-mapping> <class name="Person" table="t_person"> <id name="id"> <generator class="foreign"> <param name="property">idCard</param> </generator> </id> <property name="name"/> <one-to-one name="idCard" constrained="true"/> </class> </hibernate-mapping> |
测试类:
public class One2OneTest extends TestCase {
public void testSave1() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); IdCard idCard = new IdCard(); idCard.setCardNo("88888888888888"); Person person = new Person(); person.setName("张三"); person.setIdCard(idCard); //不会出现TransientObjectException异常 //因为一对一主键关联映射中,默认了cascade属性 session.save(person); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } } public void testLoad1() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); Person person = (Person)session.load(Person.class, 1); System.out.println("person.name=" + person.getName()); System.out.println("idCard.cardNo=" + person.getIdCard().getCardNo()); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } }
} |
hibernate一对一主键关联映射(双向关联Person<---->IdCard)
需要在idcard映射文件中加入<one-to-one>标签指向person,指示hibernate如何加载person,默认根据主键加载。
步骤基本与单向一直,只需在IdCard.java加入Person对象的引用,并在IdCard.hbm.xml加入<one-to-one>标签,相应代码如下:
IdCard.java加入: private Person person; IdCard.hbm.xml加入: <one-to-one name="person"/> |