Hibernate学习之一对一映射

Hibernate学习之一对一映射

基于外键的一对一关联关系

package com.mamh.hibernate.demo.entities;
    马哥的淘宝店:https://shop592330910.taobao.com/
public class Department {
    private int depatmentId;
    private String departmentName;

    private Manager manager;

    public Manager getManager() {
        return manager;
    }
    马哥的淘宝店:https://shop592330910.taobao.com/
    public void setManager(Manager manager) {
        this.manager = manager;
    }

    public int getDepatmentId() {
        return depatmentId;
    }

    public void setDepatmentId(int depatmentId) {
        this.depatmentId = depatmentId;
    }

    public String getDepartmentName() {
        return departmentName;
    }
    马哥的淘宝店:https://shop592330910.taobao.com/
    public void setDepartmentName(String departmentName) {
        this.departmentName = departmentName;
    }
}
package com.mamh.hibernate.demo.entities;
    马哥的淘宝店:https://shop592330910.taobao.com/
public class Manager {
    private int managerId;
    private String managerName;

    private Department department;

    public Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

    public int getManagerId() {
        return managerId;
    }

    public void setManagerId(int managerId) {
        this.managerId = managerId;
    }

    public String getManagerName() {
        return managerName;
    }

    public void setManagerName(String managerName) {
        this.managerName = managerName;
    }
}
    马哥的淘宝店:https://shop592330910.taobao.com/
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.mamh.hibernate.demo.entities">
    马哥的淘宝店:https://shop592330910.taobao.com/
    <class name="Department" table="hb_department" schema="mage">
        <id name="depatmentId">
            <column name="hb_department_id" sql-type="int(11)"/>
            <generator class="native"/>
        </id>
        <property name="departmentName" type="string">
            <column name="hb_department_name"/>
        </property>

        <!-- 使用many to one 方式来映射一对一关联关系 -->
        <many-to-one name="manager" class="Manager" column="hb_manager_id" unique="true" />

    马哥的淘宝店:https://shop592330910.taobao.com/
    </class>
</hibernate-mapping>

马哥的淘宝店:https://shop592330910.taobao.com/

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.mamh.hibernate.demo.entities">

    <class name="Manager" table="hb_manager" schema="mage">
        <id name="managerId">
            <column name="hb_manager_id" sql-type="int(11)"/>
            <generator class="native"/>
        </id>
        <property name="managerName" type="string">
            <column name="hb_manager_name"/>
        </property>

        <!--映射1to1,关联关系  -->
        <one-to-one name="department" class="Department"/>

    </class>
</hibernate-mapping>

马哥的淘宝店:https://shop592330910.taobao.com/


保存操作


    @Test
    public void testDepartment(){
        Department department = new Department();
        department.setDepartmentName("dept-aaa");

        Manager manager = new Manager();
        manager.setManagerName("mgr-aaa");

        manager.setDepartment(department);
        department.setManager(manager);

        //建议先保存没有外键的那个对象。这样会减少update语句。
        session.save(manager);
        session.save(department);
        马哥的淘宝店:https://shop592330910.taobao.com/

    }

查询操作

    @Test
    public void testGetDepartment() {
        Department department = (Department) session.get(Department.class, 1);
        System.out.println(department.getDepartmentName());

    }

默认情况下会使用懒加载。如果这里不访问manager的话就不会去查询manager对象。

Hibernate: 
    select
        department0_.hb_department_id as hb1_4_0_,
        department0_.hb_department_name as hb2_4_0_,
        department0_.hb_manager_id as hb3_4_0_ 
    from
        atguigu.hb_department department0_ 
    where
        department0_.hb_department_id=?

dept-aa

这里我继续,来查询一些manager对象。

    @Test
    public void testGetDepartment() {马哥的淘宝店:https://shop592330910.taobao.com/
        Department department = (Department) session.get(Department.class, 1);
        System.out.println(department.getManager());

    }

但是我们发现所使用的sql有点问题
开始查询department是没问题,查manager使用了left outer join左外连接。发现链接条件不对。
查询条件应该是department.manger_Id = manager.manger_id.

Hibernate: 马哥的淘宝店:https://shop592330910.taobao.com/
    select
        department0_.hb_department_id as hb1_4_0_,
        department0_.hb_department_name as hb2_4_0_,
        department0_.hb_manager_id as hb3_4_0_ 
    from
        atguigu.hb_department department0_ 
    where
        department0_.hb_department_id=?
Hibernate: 马哥的淘宝店:https://shop592330910.taobao.com/
    select
        manager0_.hb_manager_id as hb1_5_1_,
        manager0_.hb_manager_name as hb2_5_1_,
        department1_.hb_department_id as hb1_4_0_,
        department1_.hb_department_name as hb2_4_0_,
        department1_.hb_manager_id as hb3_4_0_ 
    from
        atguigu.hb_manager manager0_ 
    left outer join
        atguigu.hb_department department1_ 
            on manager0_.hb_manager_id=department1_.hb_department_id 
    where
        manager0_.hb_manager_id=?
com.mamh.hibernate.demo.entities.Manager@64ec96c6
=destroy=马哥的淘宝店:https://shop592330910.taobao.com/

正确的做法是:配置一个property-ref属性。

<one-to-one name="department" class="Department" property-ref="manager"/>
Hibernate:马哥的淘宝店:https://shop592330910.taobao.com/ 
    select
        department0_.hb_department_id as hb1_4_0_,
        department0_.hb_department_name as hb2_4_0_,
        department0_.hb_manager_id as hb3_4_0_ 
    from
        atguigu.hb_department department0_ 
    where
        department0_.hb_department_id=?
Hibernate:马哥的淘宝店:https://shop592330910.taobao.com/ 
    select
        manager0_.hb_manager_id as hb1_5_1_,
        manager0_.hb_manager_name as hb2_5_1_,
        department1_.hb_department_id as hb1_4_0_,
        department1_.hb_department_name as hb2_4_0_,
        department1_.hb_manager_id as hb3_4_0_ 
    from
        atguigu.hb_manager manager0_ 
    left outer join
        atguigu.hb_department department1_ 
            on manager0_.hb_manager_id=department1_.hb_manager_id 
    where
        manager0_.hb_manager_id=?
Hibernate:马哥的淘宝店:https://shop592330910.taobao.com/ 
    select
        department0_.hb_department_id as hb1_4_0_,
        department0_.hb_department_name as hb2_4_0_,
        department0_.hb_manager_id as hb3_4_0_ 
    from
        atguigu.hb_department department0_ 
    where
        department0_.hb_manager_id=?
com.mamh.hibernate.demo.entities.Manager@456d6c1e
=destroy=马哥的淘宝店:https://shop592330910.taobao.com/

没有外键的这一端,也就是manager这一端,需要设置property-ref来使用主键以外的列作为关联。

我们来测试单独查询manager会是咋样的?
我们发现查询manager的时候,也就是查询没有外键的那个对象会使用左外连接,
一并查出其关联的对象,并一起进行初始化。

    @Test
    public void testGetManager() {
        Manager manager = (Manager) session.get(Manager.class, 1);
        System.out.println(manager);
    }马哥的淘宝店:https://shop592330910.taobao.com/
Hibernate: 马哥的淘宝店:https://shop592330910.taobao.com/
    select
        manager0_.hb_manager_id as hb1_5_1_,
        manager0_.hb_manager_name as hb2_5_1_,
        department1_.hb_department_id as hb1_4_0_,
        department1_.hb_department_name as hb2_4_0_,
        department1_.hb_manager_id as hb3_4_0_ 
    from
        atguigu.hb_manager manager0_ 
    left outer join
        atguigu.hb_department department1_ 
            on manager0_.hb_manager_id=department1_.hb_manager_id 
    where
        manager0_.hb_manager_id=?

com.mamh.hibernate.demo.entities.Manager@2ca26d77
=destroy=马哥的淘宝店:https://shop592330910.taobao.com/

最后:不要两个表里都使用一个外键来关联另外的一个对象。


基于主键的一对一关联关系

两张表的主键一样就是基于主键的一对一映射
Department 类和Manager类还是那个类,代码不变

hbm配置映射文件需要改动一下

在department.hbm.xml中使用one to one来映射,同时要使用constrained=”true”属性。

<hibernate-mapping package="com.mamh.hibernate.demo.entities">

    <class name="Department" table="hb_department" schema="atguigu">
        <id name="depatmentId">
            <column name="hb_department_id" sql-type="int(11)"/>
            <generator class="foreign">
                <param name="property">manager</param>
            </generator>
        </id>
        <property name="departmentName" type="string">
            <column name="hb_department_name"/>
        </property>

        <!-- 使用one to one 方式来映射一对一关联关系 -->
        <!-- 采用foreign主键生成器的一端需要设置constrainend=true -->
        <one-to-one name="manager" class="Manager" constrained="true"/>


    </class>
</hibernate-mapping>
<hibernate-mapping package="com.mamh.hibernate.demo.entities">

    <class name="Manager" table="hb_manager" schema="atguigu">
        <id name="managerId">
            <column name="hb_manager_id" sql-type="int(11)"/>
            <generator class="native"/>
        </id>
        <property name="managerName" type="string">
            <column name="hb_manager_name"/>
        </property>

        <!--映射1to1,关联关系  -->
        <one-to-one name="department" class="Department" />

    </class>
</hibernate-mapping>
    @Test
    public void testSaveDepartment() {
        Department department = new Department();
        department.setDepartmentName("dept-aaa");

        Manager manager = new Manager();
        manager.setManagerName("mgr-aaa");

        manager.setDepartment(department);
        department.setManager(manager);

        //先插入manager,然后插入department。这2个调换顺序也是一样的,应为department的主键是有manager决定的,所以要先插入manager。
        session.save(manager);
        session.save(department);


    }

Hibernate: 
    insert into  atguigu.hb_manager (hb_manager_name)  values (?)
=destroy=
Hibernate: 
    insert into atguigu.hb_department (hb_department_name, hb_department_id) 
    values (?, ?)

查询操作

查询department

    @Test
    public void testGetDepartment() {
        Department department = (Department) session.get(Department.class, 1);
        System.out.println(department.getDepartmentName());

    }
Hibernate: 
    select
        department0_.hb_department_id as hb1_4_0_,
        department0_.hb_department_name as hb2_4_0_ 
    from
        atguigu.hb_department department0_ 
    where
        department0_.hb_department_id=?
dept-aaa

查询manager
此时会使用一个左外连接来查询,会连带department也查询出来。

    @Test
    public void testGetManager() {
        Manager manager = (Manager) session.get(Manager.class, 1);
        System.out.println(manager.getManagerName());
    }
Hibernate: 
    select
        manager0_.hb_manager_id as hb1_5_1_,
        manager0_.hb_manager_name as hb2_5_1_,
        department1_.hb_department_id as hb1_4_0_,
        department1_.hb_department_name as hb2_4_0_ 
    from
        atguigu.hb_manager manager0_ 
    left outer join
        atguigu.hb_department department1_ 
            on manager0_.hb_manager_id=department1_.hb_department_id 
    where
        manager0_.hb_manager_id=?
mgr-aaa
=destroy=
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值