Hibernate学习笔记(六)----关联关系中的CRUD

来源:互联网 发布:淘宝分销下单什么意思 编辑:程序博客网 时间:2024/05/22 05:11

关联关系中的CRUD(参考hibernate_1700_one2many_many2one_bi_crud)

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

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

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

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

cascade={CascadeType.ALL}

 

CascadeType取值

ALL    Cascade alloperations所有情况

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

PERSIST  Cascade persistoperation存储 persist()

REFRESH  Cascade refreshoperation刷新

REMOVE   Cascade removeoperation删除

 

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

4        铁律:双向mappedBy

5        fetch

a)    铁律:双向不要两边设置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();

 

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

    session.beginTransaction();

       User user = (User)session.load(User.class,1);

       //user对象属性改变事务commit时自动判断与数据库原有数据不同可自动update

       //此时的update@ManyToOne()中的cascadefetch参数取值无关

       user.setName("user1");

       user.getGroup().setName("group1");

       session.getTransaction().commit();

如果user改变在commit()之后且想要执行Update方法时 usergroup表同时更新则,则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();

      

7        Delete@ManyToOne()中的cascade关系

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

       session.beginTransaction();

       User user = (User)session.load(User.class,1);

       session.delete(user);

       session.getTransaction().commit();

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

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

 

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

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

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

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

              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);

       }

       //再将groupset集合设为null,相当于将group表中与user表关联的字段(userid)设为null

       //此句的前提是user表中的关联字段(groupid)已经为null,如没有则相当于破坏了一对多关联,会报错

       group.setUsers(null);

       session.delete(group);

session.getTransaction().commit();

 

8        O/RMapping 编程模型

a)   映射模型

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

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

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

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

b)   编程接口

                         i.     Jpa(不常用)

                       ii.     hibernate(现在用)

c)   数据査询语言

                         i.     HQL

                       ii.     EJBQL(JPQL)

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

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

11    练习:多对多的CRUD

teacher

student

t1

s1

t1

s2

t2

s1

t2

s2