• Hibernate 系列教程5-双向多对一


    主要讲解inverse和cascade的用法
    cascade定义的是关系两端对象到对象的级联关系;
    而inverse定义的是关系和对象的级联关系(管理外键的值)。

    inverse
    属性默认是false的,就是说关系的两端都来维护关系。
    在双向多对一里面配置到一方的集合属性上面,inverse=true,表示关系的维护(外键的值)由对方(多方)来管理

    cascade
    all : 所有情况下均进行关联操作。
    none:所有情况下均不进行关联操作。这是默认值。
    save-update:在执行save/update/saveOrUpdate时进行关联操作。
    delete:在执行delete时进行关联操作。
    delete-orphan:删除解除关系的orphan儿子

    Dept.hbm.xml

    <?xml version="1.0"?>
    <!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.jege.hibernate.two.way.onetomany">
        <class name="Dept" table="t_dept">
            <id name="id">
                <generator class="native" />
            </id>
            <property name="name" />
            <set name="users" inverse="true">
                <key column="dept_id" />
                <one-to-many class="User" />
            </set>
        </class>
    </hibernate-mapping>

    TwoCrudTest.java

    package com.jege.hibernate.two.way.onetomany;
    
    import java.util.Set;
    
    import org.hibernate.Query;
    import org.hibernate.Session;
    import org.junit.Before;
    import org.junit.Test;
    
    import com.jege.hibernate.util.HibernateUtils;
    
    /**
     * @author JE哥
     * @email 1272434821@qq.com
     * @description:双向多对一的处理
     */
    public class TwoCrudTest {
      // 单个保存:一次性保存1个部门,保存3个jege
      // 在单向多对一保存的时候需要先保存一方,不是会出现多余的update语句,影响性能
      @Before
      public void before() throws Exception {
        Dept dept = new Dept();
        dept.setName("jege部门");
    
        // 传入dept的本质是处理数据库user表的dept_id外键
        User user1 = new User("jegea", dept);
        User user2 = new User("jegeb", dept);
    
        Session session = HibernateUtils.INSTANCE.getSession();
        session.beginTransaction();
    
        System.out.println("保存之前:" + dept);
        session.save(dept);// Hibernate会自动把保存后的主键放到当前对象的id里面
        System.out.println("保存之后:" + dept);
        session.save(user1);
        session.save(user2);
    
        session.getTransaction().commit();
        session.close();
      }
    
      // 级联保存:一行save方法保存3条数据(必须建立2方的关系)
      // 修改Dept.hbm.xml
      // <set name="users" inverse="true" cascade="save-update">
      // 一次性保存:一个部门,在保存这个部门下面的2个jege
      @Test
      public void save() throws Exception {
        Dept dept = new Dept();
        dept.setName("jege部门");
    
        User user1 = new User("jege1");
        User user2 = new User("jege2");
    
        // 建立多方到一方的关系
        user1.setDept(dept);
        user2.setDept(dept);
    
        // 建立一方到多方的关系
        dept.getUsers().add(user1);
        dept.getUsers().add(user2);
    
        Session session = HibernateUtils.INSTANCE.getSession();
        session.beginTransaction();
    
        session.save(dept);// 持久化状态
    
        session.getTransaction().commit();
        session.close();
      }
    
      // 级联删除:把一方和多方同时删除:会出现3条delete语句
      // 修改Dept.hbm.xml<set name="users" inverse="true" cascade="all">
      @Test
      public void delete() throws Exception {
        Session session = HibernateUtils.INSTANCE.getSession();
        session.beginTransaction();
        session.delete(session.get(Dept.class, 1L));
        session.getTransaction().commit();
        session.close();
      }
    
      // 只删除一方,不希望删除一方包含的多方(可以先把多方的外键设置为null)
      // 方式1:修改Dept.hbm.xml<set name="users" inverse="true">
      @Test
      public void delete2() throws Exception {
        Session session = HibernateUtils.INSTANCE.getSession();
        session.beginTransaction();
        Dept dept = (Dept) session.get(Dept.class, 1L);// 持久化状态
        Set<User> users = dept.getUsers();// 持久化状态
        for (User user : users) {
          user.setDept(null);// 出现脏数据
        }
        session.delete(dept);
        session.getTransaction().commit();// 有事务,自动更新脏数据,发出update语句
        session.close();
      }
    
      // <set name="users" inverse="true">
      // 方式2:写类似dml的hql来删除
      @Test
      public void delete3() throws Exception {
        Long deptLong = 1L;
        Session session = HibernateUtils.INSTANCE.getSession();
        session.beginTransaction();
    
        // 1.先把多方的外键set null
        String hql = "update User set dept=null where dept.id=?";
        Query query = session.createQuery(hql);
        query.setLong(0, deptLong);
        System.out.println("受影响的行数:" + query.executeUpdate());
    
        // 2.删除一方
        hql = "delete from Dept where id=?";
        query = session.createQuery(hql);
        query.setLong(0, deptLong);
        System.out.println("受影响的行数:" + query.executeUpdate());
    
        session.getTransaction().commit();
        session.close();
      }
    
      // 方式1:在多方删除:先获取多方,然后删除多方
      @Test
      public void delete4() throws Exception {
        Session session = HibernateUtils.INSTANCE.getSession();
        session.beginTransaction();
        User user = (User) session.get(User.class, 1L);// 持久化状态
        session.delete(user);
        session.getTransaction().commit();
        session.close();
      }
    
      // 方式2:在一方删除多方:获取一方,通过一方来删除一条多方
      // 修改Dept.hbm.xml,实现级联删除解除关系的orphan儿子
      // <set name="users" inverse="true" cascade="delete-orphan">
      @Test
      public void delete5() throws Exception {
        Session session = HibernateUtils.INSTANCE.getSession();
        session.beginTransaction();
        Dept dept = (Dept) session.get(Dept.class, 1L);// 持久化状态
        User user = (User) session.get(User.class, 2L);// 持久化状态
        // 持久化状态dept.getUsers()
        dept.getUsers().remove(user);
        session.getTransaction().commit();// 有事务,自动脏数据更新
        session.close();
      }
    
    }
    

    源码地址

    https://github.com/je-ge/hibernate

    如果觉得我的文章对您有帮助,请予以打赏。您的支持将鼓励我继续创作!谢谢!
    微信打赏
    支付宝打赏

  • 相关阅读:
    redis常见面试题
    nginx常见的面试题
    python学习笔记(15)pymysql数据库操作
    python中的if not
    python学习笔记(24)-类与对象
    python学习笔记(23)-异常处理
    python学习笔记(22)-os文件操作模块
    Maven---pom.xml配置详解
    maven+jmeter+jenkins集成
    适配器模式
  • 原文地址:https://www.cnblogs.com/je-ge/p/6105430.html
Copyright © 2020-2023  润新知