Hibernate(7) 一对多的级联操作

版权声明:转载需经同意,谢谢! https://blog.csdn.net/Big_KK/article/details/82053099

一对多级联操作

1.级联插入操作

继续引用上篇所建立的一对多映射关系,在本例中尝试插入一个消费者以及一个地址,首先可以使用如下的方式进行:

  1. 分别创建实体对象Customer以及地址实体Address,并为其设置值。
  2. 为两个实体建立彼此的关系
  3. 将两个对象持久化

代码如下:

    @Test
    public void test(){
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction transaction = null;
        try{
            sessionFactory = HibernateUtils.getSessionFactory();
            session = sessionFactory.getCurrentSession();
            transaction = session.getTransaction();
            transaction.begin();

            //建立一个消费者并设置属性
            Customer  customer = new Customer();
            customer.setName("AA");

            //建立地址并设置地址
            Address address = new Address();
            address.setAddress("云南大理");

            //为二者建立关系,消费者为1端,可以有多个地址对象,地址实体为N端,仅可以属于一个消费者
            address.setCustomer(customer);//设置该地址所对应唯一的消费者对象
            customer.getAddressSet().add(address);//设置消费者所对应的地址,这里只添加了一个地址,可以添加多个

            //持久化
            session.save(customer);
            session.save(address);
            transaction.commit();
        }catch (Exception e){
            transaction.rollback();
        }finally {
            if(sessionFactory!=null){
                sessionFactory.close();
            }
        }
    }

按照以上的步骤就可以将两个对象持久化到数据库。当前实体的属性还非常少,如果非常多的话上面的方法就显得有些繁琐,所以我们还可以用下面的一种方式进行插入操作,针对插入操作,需要在1端(消费者实体)的set标签设置属性 cascade=”save-update 大致流程如下:

     @Test
    public void test(){
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction transaction = null;
        try{
            sessionFactory = HibernateUtils.getSessionFactory();
            session = sessionFactory.getCurrentSession();
            transaction = session.getTransaction();
            transaction.begin();

            //建立一个消费者并设置属性
            Customer  customer = new Customer();
            customer.setName("AA");

            //建立地址并设置地址
            Address address = new Address();
            address.setAddress("云南大理");

            //仅为1端实体(消费者)设置它所对应的N端实体(地址)内容
            customer.getAddressSet().add(address);//设置消费者所对应的地址

            //仅持久化1端实体(消费者实体)即可
            session.save(customer);

            transaction.commit();
        }catch (Exception e){
            transaction.rollback();
        }finally {
            if(sessionFactory!=null){
                sessionFactory.close();
            }
        }
    }

第二种方法确实是简单的写法,需要设置属性,示例的代码属性都比较少,给人感觉两种方法的代码量相差不大,错觉,错觉…..


2.级联删除操作

级联删除的时候,同样需要进入1端(消费者实体)的set标签设置属性cascade=”delete”,这样在删除一个消费者的时候,会自动删除该消费者的所有地址信息。cascade属性可以同时设置多个值,以同时具备级联删除级联插入的功能:
cascade=”delete, save-update”。而下面的级联删除操作其实与之前的常规CRUD中的删除是完全一样的,不过是我们配置了cascade属性,删除的具体过程:
     会先查询被删除信息A, 然后根据外键查询与A相关的信息B,然后将B的外键设置为null,再删除B,最后删除A

@Test
    public void test(){
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction transaction = null;
        try{
            sessionFactory = HibernateUtils.getSessionFactory();
            session = sessionFactory.getCurrentSession();
            transaction = session.getTransaction();
            transaction.begin();

            //获取要删除的对象
            Customer customer = (Customer) session.get(Customer.class, 2);
            //直接删除该对象,与之相关的地址也会被删除
            session.delete(customer);

            transaction.commit();
        }catch (Exception e){
            transaction.rollback();
        }finally {
            if(sessionFactory!=null){
                sessionFactory.close();
            }
        }
    }

3.级联修改操作

      下面演示了如何将id=2的用户地址转移给id=1的用户,首先还是先获取被转移的地址,以及所转移给的用户,然后将这两者建立关系,因为是持久态对象,所以也不用主动进行save()操作。
      但是观察控制台输出的执行语句会发现,Hibernate对外键的设置执行了两次,访问两次的原因是因为Hibernate是双向维护外键的,也就是说1段以及N端都是有外键的,所以会分别修改一次,这就出现了性能问题,但是很显然我们只是在N端设置了外键,而1端其实并没有设置。所以可以设置将1端放弃维护外键,具体方式是在1端的set标签里面设置inverse属性,该属性的默认值为false表示不放弃关系的维护,将其置为true就可以。这样的话再次删除的时候,对主键的修改仅修改一次。

 @Test
    public void test(){
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction transaction = null;
        try{
            sessionFactory = HibernateUtils.getSessionFactory();
            session = sessionFactory.getCurrentSession();
            transaction = session.getTransaction();
            transaction.begin();

//            id=2的地址原本是属于id=2的用户的,下面的代码将id=2的地址转移给id=1的用户,来演示级联修改操作

            //获取地址
            Address address = (Address) session.get(Address.class, 2);
            //获取消费者
            Customer customer = (Customer) session.get(Customer.class, 1);

            address.setCustomer(customer);
            customer.getAddressSet().add(address);
            //上面的对象都是持久态对象,所以对他们的更改可以不用save(),在下面提交的时候,会自动进行修改,属于Hibernate一级缓存的特性

            transaction.commit();
        }catch (Exception e){
            transaction.rollback();
        }finally {
            if(sessionFactory!=null){
                sessionFactory.close();
            }
        }
    }

猜你喜欢

转载自blog.csdn.net/Big_KK/article/details/82053099