美文网首页
Hibernate_6 一对一

Hibernate_6 一对一

作者: mm_cuckoo | 来源:发表于2017-12-17 15:48 被阅读18次

    外键一对一

    通俗上讲就是在一张表中设置一个外键对应另一张表的主键

    实现方法

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

      <many-to-one name="depNanamger" class="com.cfox.onetoone.Manager" unique="true">
           <column name="MANAGER_ID"/>
      </many-to-one>
      
    • 另一端需要使用one-to-one元素,该元素使用 property-ref 属性指定使用被关联实体主键以外的字段作为关联字段

      <one-to-one name="magDep" class="com.cfox.onetoone.Department" property-ref="depNanamger"></one-to-one>
      

    备注:
    如果不使用property-ref 属性的 sql 在查询的时候使用的是两张表的主键,如下SQL 中manager0_.MAG_ID=department1_.DEP_ID

        select
            manager0_.MAG_ID as MAG_ID1_1_0_,
            manager0_.MAG_NAME as MAG_NAME2_1_0_,
            department1_.DEP_ID as DEP_ID1_0_1_,
            department1_.DEP_NAME as DEP_NAME2_0_1_,
            department1_.MANAGER_ID as MANAGER_3_0_1_ 
        from
            MANAGER manager0_ 
        left outer join
            DEPARTMENTS department1_ 
                on manager0_.MAG_ID=department1_.DEP_ID 
        where
            manager0_.MAG_ID=?
    

    如果使用property-ref 属性的 sql 在查询的时候是使用设置的外键进行查询的,如下SQL 中manager0_.MAG_ID=department1_.MANAGER_ID

        select
            manager0_.MAG_ID as MAG_ID1_1_0_,
            manager0_.MAG_NAME as MAG_NAME2_1_0_,
            department1_.DEP_ID as DEP_ID1_0_1_,
            department1_.DEP_NAME as DEP_NAME2_0_1_,
            department1_.MANAGER_ID as MANAGER_3_0_1_ 
        from
            MANAGER manager0_ 
        left outer join
            DEPARTMENTS department1_ 
                on manager0_.MAG_ID=department1_.MANAGER_ID 
        where
            manager0_.MAG_ID=?
    

    实现示例代码:

    实体bean 和映射文件

    public class Manager {
        private Integer magId;
        private String magName;
        private Department magDep;
        public Integer getMagId() {
        //省略 get 和 set 方法
    }
    
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <!-- Generated 2017-12-16 13:43:26 by Hibernate Tools 3.4.0.CR1 -->
    <hibernate-mapping>
        <class name="com.cfox.onetoone.Manager" table="MANAGER">
            <id name="magId" type="java.lang.Integer">
                <column name="MAG_ID" />
                <generator class="native" />
            </id>
            <property name="magName" type="java.lang.String">
                <column name="MAG_NAME" />
            </property>
            <!-- 映射 1-1 的关联关系: 在对应的数据表中已经有外键了, 当前持久化类使用 one-to-one 进行映射 -->
            <!-- 
                没有外键的一端需要使用one-to-one元素,该元素使用 property-ref 属性指定使用被关联实体主键以外的字段作为关联字段
             -->
            <one-to-one name="magDep" class="com.cfox.onetoone.Department" ></one-to-one>
        </class>
    </hibernate-mapping>
    
    
    public class Department {
        private Integer depId;
        private String depName;
        private Manager depNanamger;
        // 省略 get 和 set 方法
    }
    
    
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <!-- Generated 2017-12-16 13:43:26 by Hibernate Tools 3.4.0.CR1 -->
    <hibernate-mapping>
        <class name="com.cfox.onetoone.Department" table="DEPARTMENTS">
            <id name="depId" type="java.lang.Integer">
                <column name="DEP_ID" />
                <generator class="native" />
            </id>
            <property name="depName" type="java.lang.String">
                <column name="DEP_NAME" />
            </property>
            <!-- 使用 many-to-one 的方式来映射 1-1 关联关系 -->
            <many-to-one name="depNanamger" class="com.cfox.onetoone.Manager" unique="true">
                <column name="MANAGER_ID"/>
            </many-to-one>
        </class>
    </hibernate-mapping>
    

    使用注意

    //在查询没有外键的实体对象时, 使用的左外连接查询, 一并查询出其关联的对象
    //并已经进行初始化. 
    Manager mgr = (Manager) session.get(Manager.class, 1);
    System.out.println(mgr.getMgrName()); 
    System.out.println(mgr.getDept().getDeptName()); 
    
    //1. 默认情况下对关联属性使用懒加载
    Department dept = (Department) session.get(Department.class, 1);
    System.out.println(dept.getDeptName()); 
    
    //2. 所以会出现懒加载异常的问题. 
    //      session.close();
    //      Manager mgr = dept.getMgr();
    //      System.out.println(mgr.getClass()); 
    //      System.out.println(mgr.getMgrName()); 
    
    //3. 查询 Manager 对象的连接条件应该是 dept.manager_id = mgr.manager_id
    //而不应该是 dept.dept_id = mgr.manager_id
    Manager mgr = dept.getMgr();
    System.out.println(mgr.getMgrName());
    
    Department dep1 = new Department();
    dep1.setDepName("Dep-AA");
    Manager man1 = new Manager();
    man1.setMagName("Man-AA");
    
    dep1.setDepNanamger(man1);
    man1.setMagDep(dep1);
    
    //保存操作
    //建议先保存没有外键列的那个对象. 这样会减少 UPDATE 语句
    //如果先保存有外键的那个对象,没有外键的那个对象保存后要更新有外键的那个对象,来设置关联关系
    /*
     * session.save(dep1);
     * session.save(man1);
     * 执行的 SQL 语句
     * Hibernate: insert into DEPARTMENTS (DEP_NAME, MANAGER_ID) values (?, ?)
     * Hibernate: insert into MANAGER (MAG_NAME) values (?)
     * Hibernate: update DEPARTMENTS set DEP_NAME=?, MANAGER_ID=? where DEP_ID=?
     */
    session.save(dep1);
    session.save(man1);
    

    主键一对一

    主键一对一就是两个表的主键进行一对一的映射关联

    实现方法

    • 基于主键的映射策略:指一端的主键生成器使用 foreign 策略,表明根据”对方”的主键来生成自己的主键,自己并不能独立生成主键. <param> 子元素指定使用当前持久化类的哪个属性作为 “对方”

      <id name="magId" type="java.lang.Integer">
          <column name="MAG_ID" />
          <generator class="foreign" >
              <param name="property">magDep</param>
          </generator>
      </id>
      
    • 采用foreign主键生成器策略的一端增加 one-to-one 元素映射关联属性,其one-to-one属性还应增加 constrained=“true” 属性;另一端增加one-to-one元素映射关联属性。

    • constrained(约束):指定为当前持久化类对应的数据库表的主键添加一个外键约束,引用被关联的对象(“对方”)所对应的数据库表主键

      <one-to-one name="magDep" class="com.cfox.onetoone.in.Department" constrained="true"></one-to-one>
      

    实现示例代码:

    实体bean 和映射文件

    public class Manager {
        private Integer magId;
        private String magName;
        private Department magDep;
        public Integer getMagId() {
        //省略 get 和 set 方法
    }
    
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <!-- Generated 2017-12-16 13:43:26 by Hibernate Tools 3.4.0.CR1 -->
    <hibernate-mapping>
        <class name="com.cfox.onetoone.Manager" table="MANAGER">
            <id name="magId" type="java.lang.Integer">
                <column name="MAG_ID" />
                <generator class="native" />
            </id>
            <property name="magName" type="java.lang.String">
                <column name="MAG_NAME" />
            </property>
            <!-- 映射 1-1 的关联关系: 在对应的数据表中已经有外键了, 当前持久化类使用 one-to-one 进行映射 -->
            <!-- 
                没有外键的一端需要使用one-to-one元素,该元素使用 property-ref 属性指定使用被关联实体主键以外的字段作为关联字段
             -->
            <one-to-one name="magDep" class="com.cfox.onetoone.Department" ></one-to-one>
        </class>
    </hibernate-mapping>
    
    
    public class Department {
        private Integer depId;
        private String depName;
        private Manager depNanamger;
        // 省略 get 和 set 方法
    }
    
    
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <!-- Generated 2017-12-16 13:43:26 by Hibernate Tools 3.4.0.CR1 -->
    <hibernate-mapping>
        <class name="com.cfox.onetoone.in.Department" table="DEPARTMENTS">
            <id name="depId" type="java.lang.Integer">
                <column name="DEP_ID" />
                <generator class="native" />
            </id>
            <property name="depName" type="java.lang.String">
                <column name="DEP_NAME" />
            </property>
            <one-to-one name="depNanamger" class="com.cfox.onetoone.in.Manager"></one-to-one>
        </class>
    </hibernate-mapping>
    

    相关文章

      网友评论

          本文标题:Hibernate_6 一对一

          本文链接:https://www.haomeiwen.com/subject/mwaywxtx.html