hibernate save/persist/update/saveOrUpdate/merge解读

来源:互联网 发布:爱淘宝 红包 编辑:程序博客网 时间:2024/06/06 20:14

hibernate的各种保存方式(save,persist,update,saveOrUpdte,merge,flush,lock)

1.       save 和 persist 方法的区别:

(1. 没有开启事物的条件下 ,save 会产生insert语句,然后事物回滚,取消插入。而persist不会产生insert语句,不会执行任何插入操作.

       (2. 当对一个 ”具备OID属性” 对象执行 save() 方法时, 会把该对象以一个新的 oid 保存到数据库中; 但执行 persist() 方法时会抛出一个异常.

2.  load 和 get 方法的区别:

       (1. hibernate 认为该 id 对应的对象(数据库记录)在数据库 中是一定存在的,进而使用代理来延迟加载该对象; 在用到该对象中的属性数据时才查询数据库,若查不到,则抛出 ObjectNotFoundEcception 异常。 注意: 并非调用 load 方法一定会生成代理对象-- 由于 session 中的缓存对于hibernate来说是个较廉价的资源,所以在load 时会先查一下session 缓存看看该id对应的对象是否存在,不存在则创建代理。

   (2. get方法:  hibernate会确认该id对应的数据是否存在,首先在 session 缓存中查找,然后在二级缓存中查找,还没有就查数据库,数据库中没有就返回null

3.  update 方法:

(1. 它只会被用于对一个 "离线对象" 进行更新操作。而一个PO对象当它已经处于 Session 状态管理的时候,是不需要写update的

(2. 若对应的记录不存在, 会抛出异常

4.   saveOrUpdate 方法:

   (1. 若持久化对象在数据库中有对应记录, 执行 update

(2. 若指定了 id, 但在数据库中还没有对应的记录, 抛出异常

(3. 若是一个瞬时对象, 执行 save

5.   merge 方法:

       1. 若持久化对象在数据库中有对应记录,

              1). 若提供的对象和数据库中记录完全一样, 只执行查询操作

              2). 否则执行查询和更新操作     

 2. 若持久化对象在数据库中没有对应的记录, 执行插入操作.


merge的作用是:新new一个对象,如果该对象设置了ID,则这个对象就当作游离态处理:

                                当ID在数据库中不能找到时,用update的话肯定会报异常,然而用merge的话,就会insert。

                                当ID在数据库中能找到的时候,update与merge的执行效果都是更新数据,发出update语句;

                                如果没有设置ID的话,则这个对象就当作瞬态处理:

                                用update的话,由于没有ID,所以会报异常,merge此时则会保存数据,根据ID生产策略生成一条数据;

Session session1 = HibernateUtils.getSession();

Transaction transaction1 = session1.beginTransaction();

Students str1 = new Students();

str1.setStu_id(4);

str1.setName("222");

session1.merge(str1);

str1.setName("333");

transaction1.commit();

session1.clear();

session1.close();

下面是当对象在第一个session关闭后,处于游离状态,

第二个session开启,又get或load一样的ID的数据出来时,在第二个session中update那个游离态对象,

          update肯定会出错,原因是程序会报持久层中已经有该对象,

因为第二个session重新从数据库中获取了一个对象成持久态,你的update会让那个游离态对象也变成持久态,

两个持久态会冲突撒,然而用merge的话,它会把第一个的对象数据赋值给已经处于持久化的那个对象中,自己本身不得变为持久态;

Session session1 = HibernateUtils.getSession();

Transaction transaction1 = session1.beginTransaction();
Students str1 = (Students)session1.get(Students.class, 2);

transaction1.commit();

session1.clear();

session1.close();
Session session2 = HibernateUtils.getSession();

Transaction transaction2 = session2.beginTransaction();

Students str2 = (Students)session2.get(Students.class, 2);

session2.merge(str1);

transaction2.commit();

session2.clear();

session2.close();

 

Session session2 = HibernateUtils.getSession();

Transaction transaction2 = session2.beginTransaction();

Students str2 = (Students)session2.get(Students.class, 2);

str1.setName("wer");

session2.merge(str1);

System.out.println(str2.getName());  

//这里改变了,说明持久态的数据也会改变

str2.setName("ee");

System.out.println(str1.getName());  

//这里不会改变,说明第一个游离态的数据没有被持久化撒;

transaction2.commit();

session2.clear();

session2.close();

阅读全文
0 0
原创粉丝点击