Hibernate关联关系中的CRUD

1、cascade  控制增删改 (即CUD)

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

 cascade仅仅是帮我们省了编程的麻烦而已,不要把它的作用看的太大
 Cascade的属性是数组格式,指明做什么操作的时候关联对象是绑在一起的

11. cascade={CascadeType.ALL}
CascadeType取值
          ALL               Cascade all operations           所有情况
MERGE        Cascade merge operation     合并(merge=save+update)
PERSIST      Cascade persist operation    存储 persist()
REFRESH    Cascade refresh operation    刷新(sessionA里面需要读sessionB改过之后的数据)

          REMOVE      Cascade remove operation   删除


2 铁律:双向关系在程序中要手动设定双向关联

3 铁律:双向mappedBy



2、Fetch   控制读(管get(),load()和其他的读取)

Fetch= FetchType.EAGER
Fetch= FetchType.LAZY(为了性能考虑

EAGER值代表取出关联 ,立即加载 

LAZY值为不取关联,延迟加载


hibernate  一对多(如Group/User)关联关系中:

一的一方:

 class Group{

@OneToMany(fetch=FetchType.LAZY)

public Set<User> getUsers(){

        }  

  }

fetch的默认值为LAZY(取group时不会将关联的users立即取出来,用到的时候再取也不迟)

多的一方:

class Users{

@ManyToOne(fetch=FetchType.EAGER)

public Group getGroup(){

        }

 }

fetch的默认值为EAGER(取user时将关联的group一同取出)


a) 铁律:双向关联关系中不要两边设置Eager(会有多余的査询语句发出)

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


另外:如果User设置了fetch=FetchType.LAZY ,则在取Group时需要在commit()之前 session还存在时调用 如:
System.out.println(user.getGroup().getName());

session.getTransaction().commit();



3、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();

      


4、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})


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

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

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

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

 









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值