• hibernate映射-基于外键的1-1关联关系


    (学习记录,错误不足之处,请您耐心指正^_^)

    hibernate基于外键的1-1映射关联关系:

       基于外键的1-1关联,其外键可以存放在任意一边,在需要存放外键的一端,增加 many-to-one 元素,为 many-to-one 元素增加 unique = "true" 属性来表示1-1关联

       另一端使用 one-to-one 元素,该元素使用 propety-ref 属性指定使用被关联实体主键以外的字段作为关联字段(即后文的mgr属性)

    一、代码示例:

    {类文件↓}

     Manager.class

     1 package com.zit.hibernate.one2one.foreign;
     2 
     3 public class Manager {
     4     
     5     private Integer mgrId;
     6     private String mgrName;
     7     
     8     private Department dept;
     9     
    10     public Integer getMgrId() {
    11         return mgrId;
    12     }
    13 
    14     public void setMgrId(Integer mgrId) {
    15         this.mgrId = mgrId;
    16     }
    17 
    18     public String getMgrName() {
    19         return mgrName;
    20     }
    21 
    22     public void setMgrName(String mgrName) {
    23         this.mgrName = mgrName;
    24     }
    25 
    26     public Department getDept() {
    27         return dept;
    28     }
    29 
    30     public void setDept(Department dept) {
    31         this.dept = dept;
    32     }
    33     
    34 }
    Manager.class

    Department.class

     1 package com.zit.hibernate.one2one.foreign;
     2 
     3 public class Department {
     4     
     5     private Integer deptId;
     6     private String deptName;
     7     
     8     private Manager mgr;
     9 
    10     public Integer getDeptId() {
    11         return deptId;
    12     }
    13 
    14     public void setDeptId(Integer deptId) {
    15         this.deptId = deptId;
    16     }
    17 
    18     public String getDeptName() {
    19         return deptName;
    20     }
    21 
    22     public void setDeptName(String deptName) {
    23         this.deptName = deptName;
    24     }
    25 
    26     public Manager getMgr() {
    27         return mgr;
    28     }
    29 
    30     public void setMgr(Manager mgr) {
    31         this.mgr = mgr;
    32     }
    33     
    34 }
    Department .class

    {映射文件↓}

    Department.hbm.xml

     1 <?xml version="1.0"?>
     2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
     3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
     4 <!-- Generated 2015-11-30 14:30:53 by Hibernate Tools 3.4.0.CR1 -->
     5 <hibernate-mapping>
     6     <class name="com.zit.hibernate.one2one.foreign.Department" table="DEPARTMENTS">
     7         <id name="deptId" type="java.lang.Integer">
     8             <column name="DEPT_ID" />
     9             <generator class="native" />
    10         </id>
    11         <property name="deptName" type="java.lang.String">
    12             <column name="DEPT_NAME" />
    13         </property>
    14         
    15         <!-- 使用many-to-one 的方式来映射 1-1 关联关系 -->
    16         <many-to-one name="mgr" class="com.zit.hibernate.one2one.foreign.Manager">
    17             <column name="MGR_ID" unique="true"></column>
    18         </many-to-one>
    19         
    20         
    21     </class>
    22 </hibernate-mapping>
    Department.hbm.xml

    Manager.hbm.xml

     1 <?xml version="1.0"?>
     2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
     3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
     4 <!-- Generated 2015-11-30 14:30:53 by Hibernate Tools 3.4.0.CR1 -->
     5 <hibernate-mapping package="com.zit.hibernate.one2one.foreign">
     6     <class name="Manager" table="MANAGERS">
     7         <id name="mgrId" type="java.lang.Integer">
     8             <column name="MGR_ID" />
     9             <generator class="native" />
    10         </id>
    11         <property name="mgrName" type="java.lang.String">
    12             <column name="MGR_NAME" />
    13         </property>
    14         
    15         <!-- 映射1-1的关联关系 :在对应是数据表中已经有外键了,使用one-to-one 进行映射-->
    16         <one-to-one name="dept" class="Department"
    17             property-ref="mgr">
    18         </one-to-one>
    19         
    20         
    21     </class>
    22 </hibernate-mapping>
    Manager.hbm.xml

    在Manager.hbm.xml中使用的是one-to-one,注意one-to-one中有子属性 property-ref务必要设置

      例:意为在department对应的表中,已经有属性mgr对应表的主键作为它的外键,

    <one-to-one name="dept" class="Department"
        property-ref="mgr">
    </one-to-one>

    若未设置property-ref属性,在查询时,会出现如下状况,看下面的sql语句:

    Hibernate: 
        select
            department0_.DEPT_ID as DEPT_ID1_0_0_,
            department0_.DEPT_NAME as DEPT_NAM2_0_0_,
            department0_.MGR_ID as MGR_ID3_0_0_ 
        from
            DEPARTMENTS department0_ 
        where
            department0_.DEPT_ID=?
    DEPT-AA
    Hibernate: 
        select
            manager0_.MGR_ID as MGR_ID1_1_1_,
            manager0_.MGR_NAME as MGR_NAME2_1_1_,
            department1_.DEPT_ID as DEPT_ID1_0_0_,
            department1_.DEPT_NAME as DEPT_NAM2_0_0_,
            department1_.MGR_ID as MGR_ID3_0_0_ 
        from
            MANAGERS manager0_ 
        left outer join
            DEPARTMENTS department1_ 
                on manager0_.MGR_ID=department1_.DEPT_ID 
        where
            manager0_.MGR_ID=?
    注意这个sql

    在导航查询时,会出现这种不正确的左外连接查询 :on manager0_.MGR_ID=department1_.DEPT_ID ,当然如果你侥幸设置的是department与manager同时插入,则他们的id号可能相同,那么你的结果也可能正确,但是这样的id号明显不能匹配查询。

    而正确的查询应该是:on manager0_.MGR_ID=department1_.MGR_ID 

    二、使用注意:

    1.插入时:同样遵循之前n-1时的插入原则,先插入1的一端,再插入多的一端。因为这种基于外键的双向1-1关联关系的映射,在一端的配置,仍然是many-to-one的形式,所以,我们插入时需要先插入one一端的对象。

       例如:本文例中的,one 为 Manager,所以插入时,先session.save(manager);在session.save(department);

    hibernate自动生成的sql如下:

    Hibernate: 
        insert 
        into
            MANAGERS
            (MGR_NAME) 
        values
            (?)
    Hibernate: 
        insert 
        into
            DEPARTMENTS
            (DEPT_NAME, MGR_ID) 
        values
            (?, ?)
    插入sql

      若先插入department,再插入manager,会多出update,与之前n-1的情况相同。

    hibernate自动生成的sql如下:

    Hibernate: 
        insert 
        into
            DEPARTMENTS
            (DEPT_NAME, MGR_ID) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            MANAGERS
            (MGR_NAME) 
        values
            (?)
    Hibernate: 
        update
            DEPARTMENTS 
        set
            DEPT_NAME=?,
            MGR_ID=? 
        where
            DEPT_ID=?
    插入sql

    2.查询时:

    若先查询Department,由department再获取对应的Manager,则会发送3条sql,获取department时发送1条,(懒加载),获取manager时,发送两条。

    department = session.get(Department.class, 1);

    若先查询Manager,由manager再获取对应的department,则只会发送1条sql,并且在获取manager时,就已经将对应的department初始化。(并没有用懒加载)

    manager = session.get(Manager.class, 2);

    (学习记录,错误不足之处,请您耐心指正^_^)

  • 相关阅读:
    中国移动 使用Linux、OpenStack
    【 【henuacm2016级暑期训练】动态规划专题 K】 Really Big Numbers
    【【henuacm2016级暑期训练】动态规划专题 J】Red-Green Towers
    【【henuacm2016级暑期训练】动态规划专题 I】Gargari and Permutations
    【【henuacm2016级暑期训练】动态规划专题 H】Greenhouse Effect
    【 【henuacm2016级暑期训练】动态规划专题 G】 Palindrome pairs
    【【henuacm2016级暑期训练】动态规划专题 F】Physics Practical
    【【henuacm2016级暑期训练】动态规划专题 E】Destroying Roads
    【【henuacm2016级暑期训练】动态规划专题 D】Writing Code
    【henuacm2016级暑期训练-动态规划专题 C】Little Girl and Maximum XOR
  • 原文地址:https://www.cnblogs.com/zitt/p/5074326.html
Copyright © 2020-2023  润新知