JavaWeb框架复习笔记-Hibernate(表与表之间的关系)

一对多

就比如一个员工属于一个公司,而一个公司有很多员工。
在这里插入图片描述

多对多

就比如用户和角色之间的关系,一个用户可以是多种角色,一种角色也可以有多种用户
在这里插入图片描述

实现一对多的流程

1.创建相应的实体类
在这里插入图片描述
在这里插入图片描述
2.让两个实体类互相表示他们的关系
在这里插入图片描述
在这里插入图片描述
3.生成他们的映射文件
先生成最基本的映射关系
在这里插入图片描述
在这里插入图片描述
接下来配置表与表之间的关联
在这里插入图片描述
在这里插入图片描述
4.创建hibernate核心配置文件,将映射文件引入
在这里插入图片描述
5.写个测试类测试一下表是否创建出来
因为session开启之后会加载hibernate核心配置文件,所以就能通过得到一个session来创建表
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实现一对多的级联保存

级联保存
手动添加一些数据上去,一个公司添加多个员工
在这里插入图片描述
在这里插入图片描述
现在我们手动删除一个公司(该公司下有员工)
发生错误,我们应该要先删除员工才能删除公司
在这里插入图片描述
现在hibernate帮我们实现这样的功能了,这就是级联操作,下面演示一下:

级联保存(复杂写法)

package com.lfm.Test;

import com.lfm.Entity.Company;
import com.lfm.Entity.Employee;
import com.lfm.Utils.HibernateUtils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.junit.Test;

/**
 * ClassName:TestOneToMany
 * Author:LFM
 * Date:2019/7/11 17:31
 **/
public class TestOneToMany {
    //演示一对多级联保存
    @Test
    public void test1(){
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;
        try {
            //得到sessionFactory
            sessionFactory = HibernateUtils.getSessionFactory();
            //得到session
            session = sessionFactory.openSession();
            //开启事务
            tx = session.beginTransaction();

            //添加一个公司,然后为这个公司添加一个员工
            //1创建公司我员工对象
            Company company = new Company();
            Employee employee = new Employee();

            //添加公司数据
            company.setName("新浪");
            //添加员工数据
            employee.setName("小花");

            //建立公司和员工的联系
            //1:将员工放入set集合里面
            company.getEmployeeSet().add(employee);
            //2:将公司放入员工里面
            employee.setCompany(company);

            //保存数据
            session.save(company);
            session.save(employee);
            //提交事务
            tx.commit();
        }catch (Exception e){
            tx.rollback();
            e.printStackTrace();
        }finally {
            session.close();
            sessionFactory.close(); //这个在web应用中就不需要关闭了
        }

    }
}

然后我们去数据库看看两张表如何了
可以看到两张表之间联系起来了(之所以是3是因为我把上次的两条记录删除了,但是主键增长策略还在)
在这里插入图片描述
在这里插入图片描述
级联保存(简化写法)
去一的那方的配置文件里面写一个配置就行了
在这里插入图片描述
然后我们演示一下效果
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

实现一对多的级联删除

直接删除公司会出错,因为有外键的存在,此时我们应该先去删除员工的信息,才能回来删除公司的
在这里插入图片描述
现在我们可以使用hibernate的配置文件来帮我们完成这一步操作
在一的那方的映射配置文件中加多一个delete属性就行了
在这里插入图片描述
写个例子来演示删除新浪公司以及他下面的所有员工
在这里插入图片描述
我们现在去看看数据库的结果
可以看出已经给删除了
在这里插入图片描述
在这里插入图片描述
我们现在来看看这个流程是怎么执行了:

Hibernate: 
    select
        company0_.cid as cid1_0_0_,//第一步根据id查找对应的公司
        company0_.name as name2_0_0_ 
    from
        t_company company0_ 
    where
        company0_.cid=?
Hibernate: 
    select
        employeese0_.cnid as cnid3_1_0_,//根据外键查找对应的员工
        employeese0_.id as id1_1_0_,
        employeese0_.id as id1_1_1_,
        employeese0_.name as name2_1_1_,
        employeese0_.cnid as cnid3_1_1_ 
    from
        t_employee employeese0_ 
    where
        employeese0_.cnid=?
Hibernate: //将员工的外键设置成null(把员工外键设置成null之后就可以删除公司了)
    update
        t_employee 
    set
        cnid=null 
    where
        cnid=?
Hibernate: //最后一步删除公司和员工
    delete 
    from
        t_employee 
    where
        id=?
Hibernate: 
    delete 
    from
        t_company 
    where
        cid=?

一对多的级联修改

假如我们把一个公司的员工转到另一个公司(跳槽)
先手动添加一个公司
在这里插入图片描述
添加一个腾讯的员工
在这里插入图片描述
现在我们把小马这个员工放到网易里面,那么他的外键应该变成4
写个测试类
可以看出已经成功实现了功能
在这里插入图片描述
在这里插入图片描述
这样做性能很低,我们看看底层sql输出

Hibernate: 
    select
        company0_.cid as cid1_0_0_,
        company0_.name as name2_0_0_ 
    from
        t_company company0_ 
    where
        company0_.cid=?
Hibernate: 
    select
        employee0_.id as id1_1_0_,
        employee0_.name as name2_1_0_,
        employee0_.cnid as cnid3_1_0_ 
    from
        t_employee employee0_ 
    where
        employee0_.id=?
Hibernate: 
    select
        employeese0_.cnid as cnid3_1_0_,
        employeese0_.id as id1_1_0_,
        employeese0_.id as id1_1_1_,
        employeese0_.name as name2_1_1_,
        employeese0_.cnid as cnid3_1_1_ 
    from
        t_employee employeese0_ 
    where
        employeese0_.cnid=?
Hibernate: //我们可以看出下面的代码做了重复的操作,影响了性能,这是因为hibernate是双向维护外键的
//所以修改了两次外键
    update
        t_employee 
    set
        name=?,
        cnid=? 
    where
        id=?
Hibernate: 
    update
        t_employee 
    set
        cnid=? 
    where
        id=?

上面的问题我们可以通过映射配置文件来让其中的一方放弃维护外键,一般让一的那方放弃维护,因为一的那方不一定了解多的那方,而多的那方肯定了解一的那方,就好比马化腾不一定知道所有的员工,但是所有的员工都知道他是老板
在这里插入图片描述
现在我们手动把数据库改回去再运行一次
在这里插入图片描述
再执行一遍那个测试类
查看底层输出,发现只运行一次外键更新,达到性能优化
在这里插入图片描述
去看看数据库结果
在这里插入图片描述

实现多对多流程

1.创建实体类
在这里插入图片描述
在这里插入图片描述
2.配置映射文件
在这里插入图片描述
在这里插入图片描述
3.引入核心配置文件中
在这里插入图片描述
写个测试类测试建表是否成功
在这里插入图片描述
最后发现是成功的
在这里插入图片描述
第三张表的结构也和我们希望的那样
在这里插入图片描述

实现多对多的级联保存

去用户配置文件配置
在这里插入图片描述
写个测试类
在这里插入图片描述
查看一下数据库内容
在这里插入图片描述
在这里插入图片描述
主要是第三张表把他们联系起来
在这里插入图片描述

实现多对多的级联删除

去映射文件配置
在这里插入图片描述写个测试类
在这里插入图片描述
发现用户1拥有的角色也消失了
在这里插入图片描述
第三张表的内容也同时消失
在这里插入图片描述
综上所述,多对多的级联删除比较少用

实现多对多的第三张表的维护

多对多都是通过第三张表来维护双方的
1.让某个用户有某种角色
我先手动添加了数据
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我现在想让lucy拥有经理这个角色
在这里插入图片描述
在这里插入图片描述
我想让某个用户没有某种角色,例如让mary没有保安这个角色
在这里插入图片描述
我们现在测试一下
在这里插入图片描述
可以看到已经成功完成了
在这里插入图片描述

总结一下
1.明确表与表之间的关系(一对多、多对多)
2.按流程生成实体类、映射文件、核心配置文件、并把最基础的映射配置好
3.配置实体类之间的关系(用set集合表示。。。)、再映射文件中用set标签配置表与表之间的关系
4.最后要注意的是多对多关系中维护是靠第三种表的,所以要把那两张表的外键关系对应好

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值