基于外键映射的1-1关联

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

<many-to-one name=”manager” class=”Manager” column=”manager_id”

         cascade=”all” unique=”true”/>

另一端需要使用one-to-one元素,该元素使用property-ref属性指定使用被关联实体主键以外的字段作为关联字段

<one-to-one name=”dept” class=”department” property-ref=”manager”/>

不使用property-ref属性的sql:

 

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=?

 

使用property-ref属性的sql:

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_.mgr_id where manager0_.mgr_id=?

 

 

 

public class Department {

   

    private Integer deptId;

    private String deptName;

   

    private Manager mgr;

 

    public Integer getDeptId() {

       return deptId;

    }

 

    public void setDeptId(Integer deptId) {

       this.deptId = deptId;

    }

 

    public String getDeptName() {

       return deptName;

    }

 

    public void setDeptName(String deptName) {

       this.deptName = deptName;

    }

 

    public Manager getMgr() {

       return mgr;

    }

 

    public void setMgr(Manager mgr) {

       this.mgr = mgr;

    }  

}

 

package com.atguigu.hibernate.one2one.foreign;

 

public class Manager {

   

    private Integer mgrId;

    private String mgrName;

   

    private Department dept;

 

    public Integer getMgrId() {

       return mgrId;

    }

 

    public void setMgrId(Integer mgrId) {

       this.mgrId = mgrId;

    }

 

    public String getMgrName() {

       return mgrName;

    }

 

    public void setMgrName(String mgrName) {

       this.mgrName = mgrName;

    }

 

    public Department getDept() {

       return dept;

    }

 

    public void setDept(Department dept) {

       this.dept = dept;

    }

}

 

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping package="com.atguigu.hibernate.one2one.foreign">

    <class name="Department" table="departments">

       <id name="deptId" type="integer">

           <column name="dept_id"></column>

           <generator class="native"></generator>

       </id>

       <property name="deptName" type="string">

           <column name="dept_name"></column>

       </property>

       <!-- 存放外键的一端 使用many-to-one 的方式来映射1-1关联关系 -->

       <many-to-one name="mgr" class="Manager" column="mgr_id" unique="true">

       </many-to-one>

    </class>

</hibernate-mapping>

 

 

 

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping package="com.atguigu.hibernate.one2one.foreign">

    <class name="Manager" table="managers">

       <id name="mgrId" type="integer">

           <column name="mgr_id"></column>

           <generator class="native"></generator>

       </id>

       <property name="mgrName" type="string">

           <column name="mgr_name"></column>

       </property>  

       <!-- 映射1-1的关联关系: 在对应的数据表中已经有外键了,当前持久化类使用

           one-to-one 来进行映射

        -->

        <!--

            没有外键的一端需要使用one-to-one 元素,该元素使用property-ref 属性

           指定使用被关联实体主键以外的字段作为关联字段,如果没有设置property-ref 的话通过没有外键的一端

           来访问关联对象的时候是使用关联对象的主键进行关联的,结果是错误的(应该使用关联实体的外键进行关联)

         -->

       <one-to-one name="dept" class="Department"

           property-ref="mgr"></one-to-one>

    </class>

</hibernate-mapping>

 

<?xml version='1.0' encoding='UTF-8'?>

<!DOCTYPE hibernate-configuration PUBLIC

          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

 

<session-factory>

    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

    <property name="connection.url">jdbc:mysql://localhost:3306/cms</property>

    <property name="connection.username">root</property>

    <property name="connection.password">123</property>

    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>

    <property name="myeclipse.connection.profile">example</property>

    <property name="hibernate.c3p0.max_size">20</property>

    <property name="hibernate.c3p0.min_size">5</property>

    <property name="hibernate.c3p0.timeout">5000</property>

    <property name="hibernate.c3p0.max_statements">100</property>

    <property name="hibernate.c3p0.idle_test_period">3000</property>

    <property name="hibernate.c3p0.acquire_increment">2</property>

    <property name="hbm2ddl.auto">update</property>

    <property name="show_sql">true</property>

    <property name="sql_format">true</property>

    <mapping resource="com/atguigu/hibernate/one2one/foreign/Manager.hbm.xml"/>

    <mapping resource="com/atguigu/hibernate/one2one/foreign/Department.hbm.xml"/>

</session-factory>

</hibernate-configuration>

 

package com.atguigu.hibernate.one2one.foreign;

 

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.Transaction;

import org.hibernate.cfg.Configuration;

import org.hibernate.service.ServiceRegistry;

import org.hibernate.service.ServiceRegistryBuilder;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

 

public class HibernateTest01 {

        

         private SessionFactory sessionFactory;

         private Session session;

         private Transaction transaction;

        

         @Before

         public void init(){

                   Configuration conf = new Configuration().configure();

                   ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(conf.getProperties()).buildServiceRegistry();

                   sessionFactory = conf.buildSessionFactory(serviceRegistry);

                   session = sessionFactory.openSession();

                   transaction = session.beginTransaction();

         }

         @After

         public void destroy(){

                   transaction.commit();

                   session.close();

                   sessionFactory.close();

         }

         @Test

         public void testSave(){

                   Department department = new Department();

                   department.setDeptName("DEPT-AA");

                  

                  Manager manager = new Manager();

                   manager.setMgrName("MGR-AA");

                  

                   //设定关联关系

                   department.setMgr(manager);

                   manager.setDept(department);

                  

                   //保存操作

                   //建议先保存没有外键列的那个对象,这样会减少update语句

                   session.save(manager);

                   session.save(department);

                  

         }

         @Test

         public void testGet(){

                   //1.默认情况下对关联属性使用懒加载

                   //2.所以会出现懒加载异常的问题

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

                   System.out.println(dept.getDeptName());

//               session.close();

//               Manager mgr = dept.getMgr();

//               System.out.println(mgr.getClass());

                   //打印上面的输出语句只是输出mgr的类的类型,不会初始化延迟加载的对象

                   //当访问对象的属性的时候才会查询晚加载的对象。

                   //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());

         }

        

         public void testGet2(){

                   //在查询没有外键的实体对象时,使用的是左外链接查询,一并查询出其关联的对象

                   //并已经进行初始化。没有延迟加载的问题出现

                   Manager mgr = (Manager) session.get(Manager.class, 1);

                   System.out.println(mgr.getMgrName());

                   System.out.println(mgr.getDept().getDeptName());

         }

}