zoukankan      html  css  js  c++  java
  • Hibernate_关联关系中的CRUD_Cascade_Fetch

    1         设定cascade以设定在持久化时对于关联对象的操作(CUD,R归Fetch管)

    2         cascade仅仅是帮我们省了编程的麻烦而已,不要把它的作用看的太大

      a)    Cascade的属性是数组格式,指明做什么操作的时候关联对象是绑在一起的

      b)    refresh = A里面需要读B改过之后的数据

      cascade={CascadeType.ALL}

    CascadeType取值

      ALL    Cascade all operations所有情况

      MERGE  Cascade merge operation合并(merge=save+update)

      PERSIST  Cascade persist operation存储 persist()

      REFRESH  Cascade refresh operation刷新

      REMOVE   Cascade remove operation删除

    3         铁律:双向关系在程序中要设定双向关联

    4         铁律:双向mappedBy

    一, save操作

    1,数据库 一对多(多对一)的双向关联

    2,类Group(一) 和User(多)

    3,saveUser方式

    @Entity
    @Table(name="t_user")
    public class User {
        private int id;
        private String name;
        private Group group;
        @ManyToOne(cascade={CascadeType.ALL})
        public Group getGroup() {
            return group;
        }
        public void setGroup(Group group) {
            this.group = group;
        }
        @Id
        @GeneratedValue
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
    @Entity
    @Table(name="t_group")
    public class Group {
        private int id;
        private String name;
        private Set<User> users = new HashSet<User>();
        @Id
        @GeneratedValue
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        @OneToMany(mappedBy="group"
            )
        
        public Set<User> getUsers() {
            return users;
        }
        public void setUsers(Set<User> users) {
            this.users = users;
        }
    }
    @Test
        public void testSaveUser() {
            User u = new User();
            u.setName("u1");
            Group g = new Group();
            g.setName("g1");
            u.setGroup(g);
            Session s = sessionFactory.getCurrentSession();
            s.beginTransaction();
            
            s.save(u);
            //s.save(g);
            s.getTransaction().commit();
        }
        

    4,saveGroup

    在Group类中设置级联

    @Entity
    @Table(name="t_group")
    public class Group {
        private int id;
        private String name;
        private Set<User> users = new HashSet<User>();
        @Id
        @GeneratedValue
        public int getId() {
            return id;
        }
        。。。。。。。
        @OneToMany(mappedBy="group",
            cascade={CascadeType.ALL}
                )
        
        public Set<User> getUsers() {
            return users;
        }
        public void setUsers(Set<User> users) {
            this.users = users;
        }
    }
    @Test
        public void testSaveGroup() {
            User u1 = new User();
            u1.setName("u1");
            User u2 = new User();
            u2.setName("u2");
            Group g = new Group();
            g.setName("g1");
            g.getUsers().add(u1);
            g.getUsers().add(u2);
            u1.setGroup(g);
            u2.setGroup(g);
            Session s = sessionFactory.getCurrentSession();
            s.beginTransaction();
            //s.save(g);
            s.save(g);
            s.getTransaction().commit();
        }

    二,get操作

    1         fetch

      a)    铁律:双向不要两边设置Eager(会有多余的査询语句发出),一般情况下,一用lazy,多用eager

      b)    对多方设置fetch的时候要谨慎,结合具体应用,一般用Lazy不用eager,特殊情况(多方数量不多的时候可以考虑,提高效率的时候可以考虑)

    @OneToMany(mappedBy="group",
    
    cascade={CascadeType.ALL}, //控制增删改(即CUD),不影响读取操作
    
    fetch=FetchType.EAGER //控制查询(即R) EAGER值代表取出关联 LAZY值为不取关联
    
                                 //多的一方fetch取值默认为LAZY 一的一方默认为EAGER
    
    )

    另外:如果User类(即多的一方)中设置fetch=FetchType.LAZY 则在调用多(即Group)的对象值的时候

    类似延迟加载 即需要在commit();之前 session还存在时调用 如:

    System.out.println(user.getGroup().getName()); 

    session.getTransaction().commit();

     三,update

    1         Update时@ManyToOne()中的cascade参数关系

          

    session.beginTransaction();
    
           User user = (User)session.load(User.class,1);
    
           //user对象属性改变 事务commit时自动判断与数据库原有数据不同 可自动update
    
           //此时的update与@ManyToOne()中的cascade或fetch参数取值无关
    
           user.setName("user1");
    
           user.getGroup().setName("group1");
    
           session.getTransaction().commit();

    如果user改变在commit()之后 且想要执行Update方法时 user与group表同时更新则,则User类的cascade={CascadeType.ALL},并在程序中写如下代码:

          

    session.beginTransaction();
    
           User user = (User)session.get(User.class,1);
    
           session.getTransaction().commit();
    
           user.setName("user1");
    
           user.getGroup().setName("group1");
    
           Session session2 = sessionFactory.getCurrentSession();
    
           session2.beginTransaction();
    
           session2.update(user);
    
           session2.getTransaction().commit();

    四,删除

     Delete时@ManyToOne()中的cascade关系

           如果User及Group类中均设为@ManyToOne(cascade={CascadeType.All}),那么在执行如下:

         

         session.beginTransaction();
    
           User user = (User)session.load(User.class,1);
    
           session.delete(user);
    
           session.getTransaction().commit();

           注意:此处删除的是 多对一(即User对Group) 中的“多”的一方(User类)

    会删除user及user对应的group,再反向对应group的user都会删除,原因就是设置了@ManyToOne(cascade={CascadeType.All})

     即是把user和group都删除

    三种方法可避免全部删除的情况:

    1.  去掉@ManyToOne(cascade={CascadeType.All})设置;

    2.  直接写Hql语句执行删除;

    @Test
        public void testDeleteUser() {
            
            testSaveGroup();
            
            Session s = sessionFactory.getCurrentSession();
            s.beginTransaction();
            
            s.createQuery("delete from User u where u.id = 1").executeUpdate();
            s.getTransaction().commit();
            
        }

    3.  将user对象的group属性设为null,相当于打断User与Group间的关联,代码如下

                session.beginTransaction();
    
                  User user = (User)session.load(User.class,1);
    
                  user.setGroup(null);
    
                  session.delete(user);
    
                session.getTransaction().commit();                

    注意:如果删除的是 多对一中的“一”的一方(Group类)时,如果使用第3种方式(user属性设为null)来打断两个对象间的关联的话,代码与之前不同,如下:

        session.beginTransaction();
    
           Group group = (Group)session.load(Group.class,1);
    
           //循环将group中的set集合下的各个user对象设为null
    
           //相当于先将数据库中user表中与group表关联的字段(即groupid)设为null
    
           for(User user :group.getUsers()){
    
                  System.out.println(user.getName());
    
                  user.setGroup(null);
    
           }
    
           //再将group的set集合设为null,相当于将group表中与user表关联的字段(即userid)设为null
    
           //此句的前提是user表中的关联字段(groupid)已经为null,如没有则相当于破坏了一对多关联,会报错
    
           group.setUsers(null);
    
           session.delete(group);
    
    session.getTransaction().commit();

    4         要想删除或者更新先做load,除了精确知道ID之外

    5         如果想消除关联关系,先设定关系为null.再删除对应记录,如果不删记录,该记录变成垃圾数据

      O/RMapping 编程模型                                                        

    a)    映射模型

                i.      jpa annotation(java提供的annotation配置--常用)

                ii.      hibernate annotation extension(Hibernate扩展的annotation配置--较少用)

                iii.      hibernate xml(Hibernate的xml配置方式--常用)

                iv.      jpa xml(java提供的xml配置--较少用)

    b)    编程接口

                 i.      Jpa(不常用)

                 ii.      hibernate(现在用)

    c)    数据査询语言

                 i.      HQL

                 ii.      EJBQL(JPQL)

  • 相关阅读:
    RocketMQ实战:生产环境中,autoCreateTopicEnable为什么不能设置为true
    x 的平方根--二分查找
    责任链模式--设计模式
    迭代器模式--设计模式
    组合模式--设计模式
    搜索旋转排序数组II
    搜索旋转排序数组--二分查找
    搜索插入位置--二分查找
    越狱详解与调试--逆向开发
    有序链表转换二叉搜索树--链表
  • 原文地址:https://www.cnblogs.com/enjoy-life-clh/p/4143979.html
Copyright © 2011-2022 走看看