上篇博客简单介绍了hibernate,并实现了一个基本映射,本篇博客将更加详细介绍映射相关内容。本文介绍一对一映射。一对一关联有两种策略:1、主键和主键关联;2、唯一外键关联,其实是多对一关联,但是把多的一端的外键设置成唯一;
1、主键主键关联:明确需求,创建实体:
一个用户只能有一个身份证号,那么user和idCard就是一对一关联,
首先看主键和主键关联,在user端维护关系,创建两个实体:
user:
public class User{
private int id;
private String name;
private IdCard idCard;//idCard的引用
//省略getter、setter
}
idCard:
public class IdCard {
private int id;
private String cardNo;
//省略getter、setter
}
2、创建实体映射文件(全局配置文件在上篇博客已经介绍到,实体映射文件写好之后,加到全局配置文件的mapping标签中):
idCard.hbm.xml(相对简单):
<?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>
<class name="com.tgb.hibernate.IdCard" table="t_idCard">
<id name="id">
<generator class="native"/>
</id>
<property name="cardNo"/>
</class>
</hibernate-mapping>
User.hbm.xml(维护关系的一端,配置相对复杂):
<?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>
<class name="com.tgb.hibernate.User" table="t_user">
<id name="id">
<!-- foreign表示一对一共享主键,两个id值一样, -->
<generator class="foreign">
<param name="property">idCard</param>
</generator>
</id>
<property name="name"/>
<!--
constrained=true,则表明存在外键与关联表对应,并且关联表中肯定存在对应的键与其对应
-->
<one-to-one name="idCard" constrained="true"/>
</class>
</hibernate-mapping>
constrained="true",表示User的主键同时是个外键,会生成外键约束语句,这样的单项关联时,如果是false不会使用lazy,会采用left join的方式查出来,true则是延迟加载。而且true的时候save和delete的顺序也是固定的了。save时先增加关联表,delete相反。
如果是双向关联,则需要在idCard的映射文件中,添加<one-to-one/>标签,关联User。
3、生成数据库表:
t_idcard:
t_user:
t_user表中没有外键约束。
4、测试类:
(简写,只写了逻辑代码):
</pre><p><pre name="code" class="java"> session.beginTransaction();
IdCard idCard = new IdCard();
idCard.setCardNo("1304545453453");
User user = new Person();
user.setName("张三");
//建立关联user.setIdCard(idCard);
session.save(user);
session.getTransaction().commit();
这样就在t_user和t_idCard表分别保存了一条记录,而且两个id是一样的。
二、唯一外键关联方法:
单向关联:
User.hbm.xml:
<?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>
<class name="com.tgb.hibernate.User" table="t_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="idCard" unique="true"/>
</class>
</hibernate-mapping>
注意使用的是many-to-one标签,而且必须使用unique="true"来限制,表示唯一性。
idCard.hbm.xml:
<?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>
<class name="com.tgb.hibernate.IdCard" table="t_idCard">
<id name="id">
<generator class="native"/>
</id>
<property name="cardNo"/>
</class>
</hibernate-mapping>
生成的数据库表(有了外键约束):
t_user:
测试就不再写了,要注意的是重点关注映射文件。
双向关联:
必须在上面的idCard.hbm.xml中添加:<one-to-one name="person" property-ref="idCard"/>
property-ref="idCard"指定了关系字段的名称。