zoukankan      html  css  js  c++  java
  • Hibernate——一对多,多对多关系

    一、一对多关系

    表中的表达

    实体中的表达

    ORM元数据配置

    1)一对多配置

    2)多对一配置

    操作关联属性

    1、添加客户,添加联系方式

    @Test
    public void func1() {
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------
    
        // 1.实例化客户实体
        Customer c = new Customer();
        c.setCust_name("鑫哥论文");
        
        // 2.实例化联系人
        LinkMan lm1 = new LinkMan();
        lm1.setLkm_name("xxx");
    
        LinkMan lm2 = new LinkMan();
        lm2.setLkm_name("jasonyu");
    
        // 3.获取客户对象中的集合,添加进去
        c.getLinkMens().add(lm1);
        c.getLinkMens().add(lm2);
    
        // 4.设置外键
        lm1.setCustomer(c);
        lm2.setCustomer(c);
    
        session.save(c);
        session.save(lm1);
        session.save(lm2);
    
        //----------------------------------------
        tx.commit();
        session.close();
    }
    

    2、只添加联系人

    @Test
    public void func2() {
    Session session = HibernateUtils.openSession();
    Transaction tx = session.beginTransaction();
    //----------------------------------------
    
    // 1.获取要操作的客户对象
    Customer customer = session.get(Customer.class, 1L);
    // 2.实例化新联系人
    LinkMan lk3 = new LinkMan();
    lk3.setLkm_name("张宝岩");
    // 3.为客户对象中的联系人集合中添加新的联系人
    customer.getLinkMens().add(lk3);
    // 4.将联系人中的custom属性设置为 客户对象
    lk3.setCustomer(customer);
    // 5.保存联系人对象(不用保存客户对象)
    session.save(lk3);
    
    //----------------------------------------
    tx.commit();
    session.close();
    }
    

    3、清除某个联系人的外键关联

    @Test
    public void func3() {
    Session session = HibernateUtils.openSession();
    Transaction tx = session.beginTransaction();
    //----------------------------------------
    
    // 1.获取要操作的客户对象
    Customer customer = session.get(Customer.class, 1L);
    // 2.获取要操作的联系人
    LinkMan lk = session.get(LinkMan.class, 2L);
    // 3.将联系人从客户对象中的联系人集合移除
    customer.getLinkMens().remove(lk);
    // 4.将联系人的customer设置为null***
    lk.setCustomer(null);
    
    //----------------------------------------
    tx.commit();
    session.close();
    }
    

    4、直接删除联系人

    @Test
    public void func4() {
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------
    
        // 1.获取要操作的客户对象
        Customer customer = session.get(Customer.class, 1L);
        // 2.获取要操作的联系人
        LinkMan lk = session.get(LinkMan.class, 2L);
        // 3.将联系人从客户对象中的联系人集合移除
        customer.getLinkMens().remove(lk);
        // 4.将联系人的customer设置为null***
        session.delete(lk);
    
        //----------------------------------------
        tx.commit();
        session.close();
    }
    

    级联操作

    元数据配置文件

     <!-- 
    	级联操作:	cascade
    		save-update: 级联保存更新(只save一个表的实例,另一个关联表的实例也save)
    		delete:级联删除(删除一个表的,另一个关联表的相应字段也被删除)
    		all:save-update+delete
    	级联操作: 简化操作.目的就是为了少些两行代码.
      -->
    
    <set name="linkMens" cascade="save-update"  >
    	<key column="lkm_cust_id" ></key>
    	<one-to-many class="LinkMan" />
    </set>
    

    结论: 简化操作.一定要用save-update,不建议使用delete.

    关系维护

    在保存时.两方都会维护外键关系,关系维护两次,冗余了;多余的维护关系语句,显然是客户这一端在维护关系

    <!-- inverse属性: 配置关系是否维护. 
    		true: customer不维护关系
    		false(默认值): customer维护关系
    		
    	inverse属性: 性能优化,提高关系维护的性能.
    	原则: 无论怎么放弃,总有一方必须要维护关系.
    	一对多关系中: 一的一方放弃,也只能一的一方放弃,多的一方不能放弃.
      -->
    <set name="linkMens" inverse="true">
    	<key column="lkm_cust_id" ></key>
    	<one-to-many class="LinkMan" />
    </set>
    

    二、多对多关系

    表中关系表达

    实体中表达

    元数据配置

    普通操作

    1、添加职位和职员

    @Test
    public void func1(){
    
        Session session = HibernateUtils.openSession();
    
        Transaction tx = session.beginTransaction();
    
        // ----------------------------------------
    
        // 1.获取两个Role 职位对象
        Role r1 = new Role();
        r1.setRole_name("保洁");
        Role r2 = new Role();
        r2.setRole_name("保安");
    
        // 2.获取两个User 职员对象
        User u1 = new User();
        u1.setUser_name("计震宇");
        User u2 = new User();
        u2.setUser_name("张宝岩");
    
        // 3.将2个用户送进两个职位下的用户列表中
        r1.getUsers().add(u1);
        r1.getUsers().add(u2);
    
        r2.getUsers().add(u1);
        r2.getUsers().add(u2);
    
        // 4.将两个职位送入2个用户下的职位列表中
        u1.getRoles().add(r1);
        u1.getRoles().add(r2);
    
        u2.getRoles().add(r1);
        u2.getRoles().add(r2);
    
        // 5.保存
        session.save(u1);
        session.save(u2);
        session.save(r1);
        session.save(r2);
    
        // ----------------------------------------
    
        tx.commit();
        session.close();
    }
    

     这种平常不过的操作,会报错,因为双方都维护第三张表,这样就维护了两次,所以我们要使用inverse属性,让一方放弃维护

    2、为计震宇添加一个职位

    @Test
    public void func1(){
    
        Session session = HibernateUtils.openSession();
    
        Transaction tx = session.beginTransaction();
    
        // ----------------------------------------
    
        // 1.获取新Role 职位对象
        Role role = new Role();
        role.setRole_name("男公关");
        // 2.获取计震宇角色
        User user = session.get(User.class, 1L);
        // 3.将计震宇放进新职位
        user.getRoles().add(role);
        // 4.将新职位放进计震宇
        role.getUsers().add(user);
        // 5.保存(如果开启了级联操作,这句可以省略)
        session.save(role);
    
        // ----------------------------------------
    
        tx.commit();
        session.close();
    }
    

    3、为计震宇解除一个角色

    @Test
    public void func1(){
    
        Session session = HibernateUtils.openSession();
    
        Transaction tx = session.beginTransaction();
    
        // ----------------------------------------
    
        // 1.获取要解除的Role 职位对象
        Role role = session.get(Role.class, 2L);
        // 2.获取计震宇角色
        User user = session.get(User.class, 1L);
        // 3.将职位从列表找中移除
        user.getRoles().remove(role);
        // 4.将计震宇从职位下的员工列表中移除(开启级联可以省略这句)
        role.getUsers().remove(user);
    
        // ----------------------------------------
    
        tx.commit();
        session.close();
    }
    

    级联操作

  • 相关阅读:
    关于DISCUZ!NT发布的问题整理!
    javascript 文字滚动显示[zhuan ]
    Bot Framework Emulator应用与调试
    Bot Framework的简单实现
    命名空间在扩展方法中的妙用
    Error:Execution failed for task ':app:transformClassesWithDexForDebug"
    C#中WebApi接口传参不再困惑:传参详解
    贝塞尔曲线
    从枚举值获取对应的文本描述
    常用正则表达式收集
  • 原文地址:https://www.cnblogs.com/x54256/p/8467698.html
Copyright © 2011-2022 走看看