Hibernate中映射关系 一对一 详解

一对一有两种关联方式:主键关联  主键既是主键也是外键
一对一主键关联:
表中:
一对一 关联映射,我们在数据库表中设计的时候,应该是一个表中关联另一张表中的id  外键 不会各自拥有。这样符合数据库设计的规范

因此我们将表分为主表和从表 比如 Person和 IDCard的例子 人和身份证 是一对一关系
因为人比身份证重要,身份证是附属于人的,所以把人看做主对象
我们将 IDCard中 添加一个Person的主键 也就是说在IDCard中添加外键 :

外键在从表中,意思就是说:外键建立在IdCard中 既是IdCard的主键 而且是外键,关联Person中的主键

对象模型:
public class Person {
private int id;
private String name;
private IdCard idCard;

public class IdCard {
private int id;
private Date usefulLife;
private Person person;


映射文件:
person中 
<hibernate-mapping package="com.coffee.one2one">
    <class name="Person">
        <id name="id">
            <generator class="native">
            </generator>
        </id>
    <property name="name"></property>
    < one-to-one name="idCard"></one-to-one>
    </class>
</hibernate-mapping>
表明1对1是关联那个类就可以了,因为外键在从表中

IdCard从对象映射文件:
<hibernate-mapping package="com.coffee.one2one">
    <class name="IdCard" table="id_card">
        <id name="id"> 
             <generator class="foreign">
            <!-- 指定由什么参数生成主键 由person里getId方法拿到ID -->
                 <param name="property">person</param>
        </generator>
        </id>
        <property name="usefulLife" column="useful_life"></property>
        <!-- constrained=true 约束为真 引用主对象的id -->
         <one-to-one name="person" constrained="true"></one-to-one>
    </class>
</hibernate-mapping>

不仅要指定关联的对象 而且要指定外键 : 
<generator class="foreign">
<param name="property">person</param>

不仅如此:
还要添加外键约束:constrained="true"

这里要提到一种主键生成器:
foreign:
用这种生成器就是hibernate在保存idcard的时候 通过关联另一种表的属性所获得的(person id); 
保存 检索分析:
保存:

从对象中没有主对象是不能保存的 

主对象中没有从对象 是可以保存的


检索:

按照我自己的思路:当我们再查询主对象的时候,并得到从对象的时候,应该是先查询主对象,然后再产生一条select语句查询从对象,但是

查询主对象的时候 是用的左链接查询( left outer join ), 只有一条select语句 


查询从对象的时候,用了两次查询,更为复杂

先查询从对象IdCard 然后再查询主对象Person 再用 left outer join + 其他条件



一对一外键关联:

表结构:

idCard中不再将主键作为外键
而是单独设置一个外键关联person中的主键
从表结构上 可以看出
和多对一有些类似,但是区别在于 这里不能多个IdCard对于同一个Person

对象结构:不变

所以映射文件上稍微做点儿改变:
IdCard:
<hibernate-mapping package="com.coffee.one2oneFK">
    <class name="IdCard" table="id_card">
        <id name="id">
            <generator class="native"></generator> //生成器改变:不需要外键生成器
        </id>
        <property name="usefulLife" column="useful_life"></property>
        <!-- 和对一设置一样,不过叫上多的一方唯一的属性 并指定属性名为person_id规范-->
         <many-to-one name="person" unique="true" column="person_id"></many-to-one>
    </class>
</hibernate-mapping>

person:
<hibernate-mapping package="com.coffee.one2oneFK">
    <class name="Person">
        <id name="id">
            <generator class="native">
            </generator>
        </id>
        <property name="name"></property>
         <!-- property-ref:设置关联类的属性名,此属性和本类的主键相对应 默认值为关联类的主键 -->
        <!-- 如果有此属性 则Person没有关联上IdCard 就为单向关联 不能通过person查到ID了 -->
         <one-to-one name="idCard" property-ref="person"></one-to-one>
    </class>
</hibernate-mapping>
这里和一对一主键关联不同的是,从对象的角度在思考,需要指定 idcard关联的属性 person,没有去指定column是什么字段  一对一主键关联没有指定 见上映射文件


一对一有两种关联方式:主键关联  主键既是主键也是外键
一对一主键关联:
表中:
一对一 关联映射,我们在数据库表中设计的时候,应该是一个表中关联另一张表中的id  外键 不会各自拥有。这样符合数据库设计的规范

因此我们将表分为主表和从表 比如 Person和 IDCard的例子 人和身份证 是一对一关系
因为人比身份证重要,身份证是附属于人的,所以把人看做主对象
我们将 IDCard中 添加一个Person的主键 也就是说在IDCard中添加外键 :

外键在从表中,意思就是说:外键建立在IdCard中 既是IdCard的主键 而且是外键,关联Person中的主键

对象模型:
public class Person {
private int id;
private String name;
private IdCard idCard;

public class IdCard {
private int id;
private Date usefulLife;
private Person person;


映射文件:
person中 
<hibernate-mapping package="com.coffee.one2one">
    <class name="Person">
        <id name="id">
            <generator class="native">
            </generator>
        </id>
    <property name="name"></property>
    < one-to-one name="idCard"></one-to-one>
    </class>
</hibernate-mapping>
表明1对1是关联那个类就可以了,因为外键在从表中

IdCard从对象映射文件:
<hibernate-mapping package="com.coffee.one2one">
    <class name="IdCard" table="id_card">
        <id name="id"> 
             <generator class="foreign">
            <!-- 指定由什么参数生成主键 由person里getId方法拿到ID -->
                 <param name="property">person</param>
        </generator>
        </id>
        <property name="usefulLife" column="useful_life"></property>
        <!-- constrained=true 约束为真 引用主对象的id -->
         <one-to-one name="person" constrained="true"></one-to-one>
    </class>
</hibernate-mapping>

不仅要指定关联的对象 而且要指定外键 : 
<generator class="foreign">
<param name="property">person</param>

不仅如此:
还要添加外键约束:constrained="true"

这里要提到一种主键生成器:
foreign:
用这种生成器就是hibernate在保存idcard的时候 通过关联另一种表的属性所获得的(person id); 
保存 检索分析:
保存:

从对象中没有主对象是不能保存的 

主对象中没有从对象 是可以保存的


检索:

按照我自己的思路:当我们再查询主对象的时候,并得到从对象的时候,应该是先查询主对象,然后再产生一条select语句查询从对象,但是

查询主对象的时候 是用的左链接查询( left outer join ), 只有一条select语句 


查询从对象的时候,用了两次查询,更为复杂

先查询从对象IdCard 然后再查询主对象Person 再用 left outer join + 其他条件



一对一外键关联:

表结构:

idCard中不再将主键作为外键
而是单独设置一个外键关联person中的主键
从表结构上 可以看出
和多对一有些类似,但是区别在于 这里不能多个IdCard对于同一个Person

对象结构:不变

所以映射文件上稍微做点儿改变:
IdCard:
<hibernate-mapping package="com.coffee.one2oneFK">
    <class name="IdCard" table="id_card">
        <id name="id">
            <generator class="native"></generator> //生成器改变:不需要外键生成器
        </id>
        <property name="usefulLife" column="useful_life"></property>
        <!-- 和对一设置一样,不过叫上多的一方唯一的属性 并指定属性名为person_id规范-->
         <many-to-one name="person" unique="true" column="person_id"></many-to-one>
    </class>
</hibernate-mapping>

person:
<hibernate-mapping package="com.coffee.one2oneFK">
    <class name="Person">
        <id name="id">
            <generator class="native">
            </generator>
        </id>
        <property name="name"></property>
         <!-- property-ref:设置关联类的属性名,此属性和本类的主键相对应 默认值为关联类的主键 -->
        <!-- 如果有此属性 则Person没有关联上IdCard 就为单向关联 不能通过person查到ID了 -->
         <one-to-one name="idCard" property-ref="person"></one-to-one>
    </class>
</hibernate-mapping>
这里和一对一主键关联不同的是,从对象的角度在思考,需要指定 idcard关联的属性 person,没有去指定column是什么字段  一对一主键关联没有指定 见上映射文件


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值