Hibernamte框架的学习--第三天

一、 对多|多对一

  1.  关系表达

   1)表中的表达

  2)实体中的表达

  3)元数据中的表达

  一对多

  

      多对一

  2.  操作

      1). 操作关联属性

/**
 * 一对多|多对一
 * @author vanguard
 *
 */
public class Demo {
    /**
     * 保存客户以及客户下的联系人
     */
    @Test
    public void fun1() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        Customer c = new Customer();
        c.setCust_name("腾讯");
        
        LinkMan lm1 = new LinkMan();
        lm1.setLkm_name("马化腾");
        
        LinkMan lm2 = new LinkMan();
        lm2.setLkm_name("马总");
        
        //表示一对多,一个客户下有多个联系人
        c.getLinkMens().add(lm1);
        c.getLinkMens().add(lm2);
        
        //表示多对一,多个联系人对应一个客户
        lm1.setCustomer(c);
        lm2.setCustomer(c);
        
        //执行保存操作
        session.save(c);
        session.save(lm1);
        session.save(lm2);    
        
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }
    
    /**
     * 为客户添加联系人
     */
    @Test
    public void fun2() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        
        //1>获得要操作的客户对象
        Customer c = session.get(Customer.class, 1l);
        //2>创建联系人,将客户设置到联系人中
        LinkMan lm1 = new LinkMan();
        lm1.setLkm_name("QQ");
        lm1.setCustomer(c);
        //3>为客户添加联系人
        c.getLinkMens().add(lm1);
        //4>执行保存
        session.save(lm1);
        
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }
    
    /**
     * 删除客户的联系人
     */
    @Test
    public void fun3() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        
        //1>获得要操作的客户对象
        Customer c = session.get(Customer.class, 1l);
        //2>获得要操作的联系人对象
        LinkMan lm = session.get(LinkMan.class, 3l);
        //3>移除客户中对应的联系人
        c.getLinkMens().remove(lm);
        //4>删除联系人中对应的客户
        lm.setCustomer(null);
        
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }
}

  2)进阶操作

            级联操作

        

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

        测试代码:

/**
 * 一对多|多对一
 * 级联操作:cascade
 *     save-update:级联保存更新
 *     delete:级联删除
 *  all: save-updata+delete
 * 级联操作:简化操作。目的为了少写代码
 * @author vanguard
 *
 */
public class Demo02 {
    /**
     * 保存客户以及客户下的联系人
     * 级联操作
     * cascade:save-update
     * 
     */
    @Test
    public void fun1() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        Customer c = new Customer();
        c.setCust_name("腾讯");
        
        LinkMan lm1 = new LinkMan();
        lm1.setLkm_name("马化腾");
        
        LinkMan lm2 = new LinkMan();
        lm2.setLkm_name("马总");
        
        //表示一对多,一个客户下有多个联系人
        c.getLinkMens().add(lm1);
        c.getLinkMens().add(lm2);
        
        //表示多对一,多个联系人对应一个客户
        lm1.setCustomer(c);
        lm2.setCustomer(c);
        
        //执行保存操作
        session.save(c);
//        session.save(lm1);
//        session.save(lm2);    
        
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }
    
    /**
     * 
     * 删除客户时,级联删除客户下的联系人
     * cascade:delete
     * 不建议使用delete
     */
    @Test
    public void fun2() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        
        //1>获得要操作的客户对象
        Customer c = session.get(Customer.class, 1l);
        //2>调用delete删除
        session.delete(c);
        
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }
    
    /**
     * 保存客户以及客户下的联系人
     * 级联操作
     * cascade:save-update
     * 客户是主控方,当客户执行保存、更新、删除操作时,联系人也会执行相同的操作
     * 不需要联系人自己维护
     */
    @Test
    public void fun3() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        Customer c = new Customer();
        c.setCust_name("阿里");
        
        LinkMan lm1 = new LinkMan();
        lm1.setLkm_name("马云");
        
        //表示一对多,一个客户下有多个联系人
        c.getLinkMens().add(lm1);
        
        //已经设定级联操作,客户为主控方,所以,不用联系人自己维护
        
        //执行保存操作
        session.save(c);

        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }
}

 

 

 

            关系维护

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

            

 

         

          测试代码:

/**
 * 一对多|多对一
 *  关系维护
 *  inverse属性:配置是否维护关系
 *   true:不维护关系
 *   false:维护关系(默认)
 *  inverse属性:性能优化,提高关系维护的性能
 *  原则:无论怎样,总有一方放弃维护关系
 *  一对多关系中,一的一方放弃。多的一方不能放弃维护
 *  一的一方放弃维护关系
 * @author vanguard
 *
 */
public class Demo03 {
    /**
     * 保存客户以及客户下的联系人
     * 客户放弃维护关系
     * 由联系人来维护关系
     */
    @Test
    public void fun1() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        Customer c = new Customer();
        c.setCust_name("腾讯");
        
        LinkMan lm1 = new LinkMan();
        lm1.setLkm_name("马化腾");
        
        LinkMan lm2 = new LinkMan();
        lm2.setLkm_name("马总");
        
        //由于客户已经放弃维护关系,所以,客户不用自己添加联系人
        //最后客户和联系人都要保存
        //表示一对多,一个客户下有多个联系人
//        c.getLinkMens().add(lm1);
//        c.getLinkMens().add(lm2);
        
        //由联系人维护关系
        //表达多对一,联系人属于哪个客户
        lm1.setCustomer(c);
        lm2.setCustomer(c);
        
        //执行保存操作
        session.save(c);
        session.save(lm1);
        session.save(lm2);
        
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }
    
    /**
     * 
     * 删除客户时,删除客户下的联系人
     * (1)级联关系为delete
     * cascade:delete
     * (2)客户自己维护关系
     * inverse:false
     */
    @Test
    public void fun2() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        
        //1>获得要操作的客户对象
        Customer c = session.get(Customer.class, 1l);
        //2>调用delete删除
        session.delete(c);
        
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }
}

二、多对多

  1.  关系表达

    1)表中

           

   2)对象中

         

  3)ORM元数据

             

  

  2  操作

    1) 操作关联属性   

   /**
     * 保存用户及角色
     * 多对多关系中,两方都会自动维护关系,从而导致中间表添加两次主键,抛出异常
     * 所以,一定要有一方放弃维护关系
     * 选择谁来放弃要看业务方向
     * 例如,录入员工时,需要为员工制定所属的角色,所以,角色一方应该放弃维护关系
     */
    @Test
    public void fun1() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        
        //1>创建两个用户对象
        User u1 = new User();
        u1.setUser_name("张三");
        User u2 = new User();
        u2.setUser_name("李四");
        //2>创建两个角色
        Role r1 = new Role();
        r1.setRole_name("保安");
        Role r2 = new Role();
        r2.setRole_name("清洁工");
        //3>用户中添加角色
        u1.getRoles().add(r1);
        u1.getRoles().add(r2);
        u2.getRoles().add(r1);
        u2.getRoles().add(r2);    
        //4>角色中添加用户
        r1.getUsers().add(u1);
        r1.getUsers().add(u2);
        r2.getUsers().add(u1);
        r2.getUsers().add(u2);
        //5>保存用户及角色
        session.save(u1);
        session.save(u2);
        session.save(r1);
        session.save(r2);
        
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }

  3  操作进阶

       1)inverse属性

             

     2)级联属性

          

         测试代码:

        

/**
 * 多对多关系操作
 * @author vanguard
 *
 */
public class Demo {
    /**
     * 保存用户及角色
     * 多对多关系中,两方都会自动维护关系,从而导致中间表添加两次主键,抛出异常
     * 所以,一定要有一方放弃维护关系
     * 选择谁来放弃要看业务方向
     * 例如,录入员工时,需要为员工制定所属的角色,所以,角色一方应该放弃维护关系
     */
    @Test
    public void fun1() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        
        //1>创建两个用户对象
        User u1 = new User();
        u1.setUser_name("张三");
        User u2 = new User();
        u2.setUser_name("李四");
        //2>创建两个角色
        Role r1 = new Role();
        r1.setRole_name("保安");
        Role r2 = new Role();
        r2.setRole_name("清洁工");
        //3>用户中添加角色
        u1.getRoles().add(r1);
        u1.getRoles().add(r2);
        u2.getRoles().add(r1);
        u2.getRoles().add(r2);    
        //4>角色中添加用户
        r1.getUsers().add(u1);
        r1.getUsers().add(u2);
        r2.getUsers().add(u1);
        r2.getUsers().add(u2);
        //5>保存用户及角色
        session.save(u1);
        session.save(u2);
        session.save(r1);
        session.save(r2);
        
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }
    
    /**
     * 给用户添加角色
     * 级联操作: save-update
     * 主控方是用户,更新用户时,自动更新角色
     */
    @Test
    public void fun2() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        
        //1>获得添加角色的用户
        User user = session.get(User.class, 1l);
        //2>创建添加角色的对象
        Role r = new Role();
        r.setRole_name("前台");
        //3> 用户中添加角色
        user.getRoles().add(r);
        //4>角色中添加用户
        r.getUsers().add(user);
        //5>执行保存
        //session.save(r);
        
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }
    
    /**
     * 删除指定用户的一个角色
     */
    @Test
    public void fun3() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        
        //1>获得删除角色的用户
        User user = session.get(User.class, 1l);
        //2>获得要的角色
        Role r1 = session.get(Role.class, 1l);
        Role r2 = session.get(Role.class, 2l);
        //3>将角色从用户集合中移除
        user.getRoles().remove(r1);
        user.getRoles().remove(r2);
        
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }
}

 

posted @ 2017-09-04 22:37  Vanguard  阅读(582)  评论(0编辑  收藏  举报