zoukankan      html  css  js  c++  java
  • Hibernate一对多OnetoMany

     ------------------------Hibernate一对多OnetoMany
    要点:
    配置在一端。
    1.如果是单向关联,即只在一端配置OneToMany,多端不配置ManyToOne。则会创建一张关系表。
    2.如果在单向关联的OneToMany上加上@JoinColumn,则会在多端增加一个外键维护关系,而不单独创建关系表。
    3.可以配置级联操作 @OneToMany(cascade=CascadeType.ALL),保存一端的时候保存多端
    4.如果是双向关联,即在一端配置OneToMany,多端配置ManyToOne,则在多端增加外键字段维护关系,
    并且要使用mappedBy或者是inverse确保只有一端维护关系
    
    
    2.单向关联
    @Entity
    public class User {
    
    	@Id
    	@GeneratedValue
    	private long id;
    	
    	@Column(name="name")
    	private String name;
    	
    	@OneToMany(cascade=CascadeType.ALL)
    	@JoinColumn
    	private Set<Role> roles = new HashSet<Role>();
    	
    }
    
    @Entity
    public class Role {
    	@Id
    	@GeneratedValue
    	private long id;
    	@Column
    	private String name;
    }
    
    执行:
            User user = new User();
            user.setName("zhangsan");
            
            Role r1= new Role();
            r1.setName("ADMIN");
            Role r2= new Role();
            r2.setName("EDITOR");
            
            user.getRoles().add(r1);
            user.getRoles().add(r2);
            
            session.save(user);
    
    
    结果:
    Hibernate: 
        insert 
        into
            User
            (name, id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            Role
            (name, id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            Role
            (name, id) 
        values
            (?, ?)
    Hibernate: 
        update
            Role 
        set
            roles_id=? 
        where
            id=?
    Hibernate: 
        update
            Role 
        set
            roles_id=? 
        where
            id=?
    保存user后保存两个role 然后更新外键。多两条更新语句。
    
    
    执行:保存user后删除一个role对象。        
    		User user = new User();
            user.setName("zhangsan");
            
            Role r1= new Role();
            r1.setName("ADMIN");
            Role r2= new Role();
            r2.setName("EDITOR");
            
            user.getRoles().add(r1);
            user.getRoles().add(r2);
            
            session.save(user);
            user.getRoles().remove(r1);
    结果:
    Hibernate: 
        insert 
        into
            User
            (name, id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            Role
            (name, id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            Role
            (name, id) 
        values
            (?, ?)
    Hibernate: 
        update
            Role 
        set
            roles_id=? 
        where
            id=?
    
    保存user后保存两个role,然后更新被删除role的外键为Null。此时并没有删除role这个数据。
    只需要增加orphanRemoval=true,则会删除已经没有关联关系的子实体
    @Entity
    public class User {
    
    	@Id
    	@GeneratedValue
    	private long id;
    	
    	@Column(name="name")
    	private String name;
    	
    	@OneToMany(cascade=CascadeType.ALL,orphanRemoval=true)
    	@JoinColumn
    	private Set<Role> roles = new HashSet<Role>();
    }
    
    结果:
    Hibernate: 
        insert 
        into
            User
            (name, id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            Role
            (name, id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            Role
            (name, id) 
        values
            (?, ?)
    Hibernate: 
        update
            Role 
        set
            roles_id=? 
        where
            id=?
    Hibernate: 
        delete 
        from
            Role 
        where
            id=?
    		
    将移除的子实体更新外键为null,然后执行删除,效率一般。
    
    
    
    4.双向关联
    要点:关系必须双向都设置,业务代码中关系也必须双向设置
    mappedBy指向多端实体里的一端变量名
    inverse和mappedBy是同一个东西,只是inverse是用于xml配置,而mappedBy则是用于注解中。 
    只有OneToOne,OneToMany,ManyToMany上才有mappedBy属性,ManyToOne不存在该属性;
    
    
    @Entity
    public class User {
    
    	@Id
    	@GeneratedValue
    	private long id;
    	
    	@Column(name="name")
    	private String name;
    	
    	@OneToMany(cascade=CascadeType.ALL,mappedBy="user")//由多端维护关系
    	private Set<Role> roles = new HashSet<Role>();
    }
    
    @Entity
    public class Role {
    	@Id
    	@GeneratedValue
    	private long id;
    	@Column
    	private String name;
    	@ManyToOne
    	private User user;
    }
    
    -------------------mappedBy 只保存一端
    T1
    执行:
            User user = new User();
            user.setName("zhangsan");
            
            Role r1= new Role();
            r1.setName("ADMIN");
            Role r2= new Role();
            r2.setName("EDITOR");
            //业务代码中双向设置关系
            user.getRoles().add(r1);
            user.getRoles().add(r2);
            r1.setUser(user);
            r2.setUser(user);
    		
    		session.save(user);
    结果:
    Hibernate: 
        insert 
        into
            User
            (name, id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            Role
            (name, user_id, id) 
        values
            (?, ?, ?)
    Hibernate: 
        insert 
        into
            Role
            (name, user_id, id) 
        values
            (?, ?, ?)
    执行3条语句,插入结果正确。将保存操作传递到多端了,然后进行了保存。
    
    --------------------------------mappedBy 先保存多端,再保存一端
            User user = new User();
            user.setName("zhangsan");
            
            Role r1= new Role();
            r1.setName("ADMIN");
            Role r2= new Role();
            r2.setName("EDITOR");
            
            user.getRoles().add(r1);
            user.getRoles().add(r2);
            r1.setUser(user);
            r2.setUser(user);
            session.save(r1);
            session.save(r2);
            session.save(user);//无此句则报错,因为user为瞬时态,而role端无级联操作
    结果:
    Hibernate: 
        insert 
        into
            Role
            (name, user_id, id) 
        values
            (?, ?, ?)
    Hibernate: 
        insert 
        into
            Role
            (name, user_id, id) 
        values
            (?, ?, ?)
    Hibernate: 
        insert 
        into
            User
            (name, id) 
        values
            (?, ?)
    Hibernate: 
        update
            Role 
        set
            name=?,
            user_id=? 
        where
            id=?
    Hibernate: 
        update
            Role 
        set
            name=?,
            user_id=? 
        where
            id=?
    先保存两个role,然后保存user。role负责关系维护,又更新了关系外键。
    
    ---------------------mappedBy 只保存一端,并删除一端集合的一个数据 
    
    执行:
            User user = new User();
            user.setName("zhangsan");
            
            Role r1= new Role();
            r1.setName("ADMIN");
            Role r2= new Role();
            r2.setName("EDITOR");
            //业务代码中双向设置关系
            user.getRoles().add(r1);
            user.getRoles().add(r2);
            r1.setUser(user);
            r2.setUser(user);
    		
    		session.save(user);
    		user.getRoles().remove(r1);
    
    
    结果:
    Hibernate: 
        insert 
        into
            User
            (name, id) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            Role
            (name, user_id, id) 
        values
            (?, ?, ?)
    Hibernate: 
        insert 
        into
            Role
            (name, user_id, id) 
        values
            (?, ?, ?)
    
    没有进行删除操作。User不负责关系维护,操作失败。
    当指定orphanRemoval=true时删除成功!
    
    
    ---------级联删除
    --------------------直接删除一端(数据为T1操作后的数据)
            User user = session.get(User.class, 170l);
            session.remove(user);
    		
    结果:
    Hibernate: 
        delete 
        from
            Role 
        where
            id=?
    Hibernate: 
        delete 
        from
            Role 
        where
            id=?
    Hibernate: 
        delete 
        from
            User 
        where
            id=?

    删除了一端和所有多端。删除进行了级联传递,先删除多端的两个Role,然后删除用户。
    此时确先删除了多端,然后删除一端?直接先删除一端是不可能的

    --------------------直接删除多端
    Role r = session.get(Role.class, 175l);
    session.remove(r);
    结果:
    Hibernate:
    delete
    from
    Role
    where
    id=?
    执行成功。相当于执行了mantoone的删除

    //删除
    User user = session.get(User.class, 167l);
    Role role = session.get(Role.class, 168l);
    System.out.println(user.getName());
    System.out.println(role.getName());
    user.getRoles().remove(role);//当载入内存后,必须解除关系,再删除
    session.remove(role);//删除成功

      

  • 相关阅读:
    Java类加载机制
    Java内存模型
    遍历集合的常见方式,排序,用lambda表示是怎样的
    包和访问权限修饰符,.单例设计模式,.Object类常用方法,.内部类
    接口
    继承
    面向对象的四大特征 封装 继承 多态 抽象
    面向对象
    二维数组及Arrays工具类
    数组(冒泡,选择,排序)
  • 原文地址:https://www.cnblogs.com/beenupper/p/6816771.html
Copyright © 2011-2022 走看看