Java实战之02Hibernate-03Session中的常用方法
九、Session中的常用方法
1、save方法
都是临时态————>持久态
2、persist方法
作用:
持久化临时态对象。
与save方法的区别:
开始了事务:persist和save没有区别。
不开启事务:
persist:什么都不会做。
save:
hibernate3:计划保存数据,因为没有开启事务,自动回滚。
hibernate5:提供一个内置事务执行保存操作。
1 /* 2 * save方法和persist方法 3 * 共同点: 4 * 都是把临时态对象转成持久态 5 * 区别: 6 * 1、提供者不一样 7 * save方法是hibernate提供的 8 * persist方法是JPA规范提供的 Java Persistence API 9 * 2、在没有事务的支持下 10 * save方法: 11 * hibernate5:会用框架内置的事务执行保存操作。 12 * hibernate3:就会执行保存,但是没有明确的提交操作,在超时后,事务自动回滚。 13 * persist方法: 14 * 什么都不去做。 15 * 16 */ 17 @Test 18 public void test2(){ 19 Student s1 = new Student();//临时态 20 s1.setName("test3"); 21 s1.setGender("female"); 22 s1.setBirthday(new Date()); 23 24 25 Session s = HibernateUtil.getSession(); 26 //Transaction tx = s.beginTransaction(); 27 s.persist(s1);//持久态 28 //tx.commit(); 29 s.close(); 30 } 31 32 @Test 33 public void test1(){ 34 Student s1 = new Student();//临时态:没有OID,和session没有关系 35 s1.setName("test4"); 36 s1.setGender("male"); 37 s1.setBirthday(new Date()); 38 39 40 Session s = HibernateUtil.getSession(); 41 Transaction tx = s.beginTransaction(); 42 s.save(s1);//持久态:有OID,和session有关系 43 tx.commit(); 44 s.close(); 45 }
3、update方法
把脱管态-------->持久态
3.1、若脱管态对象的属性没有发生变化,也会执行update语句。可以在<class select-before-update="true">改变。开发中可以对于属性不经常变化的实体做此配置
解决问题:
3.2、update一个脱管态对象时,如果已经存在OID相同的持久态对象,则报错
3.3、update一个脱管态对象时,数据库不存在相应记录(被别的程序删除),亦错
/* * update方法 * 把一个脱管态的对象转成持久态 */ /* * 问题3: * 当我们持久化一个脱管态的对象时,如果该对象被别的程序删除了,则会报错 */ @Test public void test5(){ Session s2 = HibernateUtil.getSession(); Transaction tx2 = s2.beginTransaction(); Student student2 = s2.get(Student.class, 1);//持久态 student2.setGender("female"); s2.update(student2);//把脱管态对象转成持久态 tx2.commit(); s2.close(); } /* * 问题2: * 当我们持久化一个脱管态对象时,如果在session的一级缓存之中,已经包含了有相同OID的对象,则会报错。 * 解决办法: * 使用使用merge方法 */ @Test public void test4(){ Session s1 = HibernateUtil.getSession(); Transaction tx1 = s1.beginTransaction(); Student studnet1 = s1.get(Student.class,1);//持久态 tx1.commit(); s1.close(); System.out.println(studnet1);//脱管态:有OID,和Session没有关系 Session s2 = HibernateUtil.getSession(); Transaction tx2 = s2.beginTransaction(); Student student2 = s2.get(Student.class, 1);//持久态 s2.update(studnet1);//把脱管态对象转成持久态 tx2.commit(); s2.close(); } /* * 问题1: * 当我们使用update持久一个脱管态对象时,就算没有修改实体对象的数据,也会执行update语句。 * 解决办法: * select-before-update * 配置位置:映射文件的class元素上 * <class name="Student" table="student" select-before-update="true"> * 取值: * true:在更新之前,执行查询 * false:在更新之前不执行查询。默认值 */ @Test public void test3(){ Session s1 = HibernateUtil.getSession(); Transaction tx1 = s1.beginTransaction(); Student s = s1.get(Student.class,1);//持久态 tx1.commit(); s1.close(); System.out.println(s);//脱管态:有OID,和Session没有关系 Session s2 = HibernateUtil.getSession(); Transaction tx2 = s2.beginTransaction(); s2.update(s);//持久态 tx2.commit(); s2.close(); }
4、saveOrUpdate方法
作用:保存或修改
临时态————>持久态:保存
脱管态————>持久态:更新
依据对象的状态来确定save还是update
特殊情况:
当在对象的映射xml文件中,<id中设置了unsaved-value>,且和OID保持一致时,就不再把对象看成游离态而是临时态。
1 /* 2 * saveOrUpdate 3 * 作用: 4 * 执行保存或者更新 5 * 执行依据: 6 * 依据的是对象的状态。 7 * 如果对象是临时态,则执行save 8 * 如果对象是脱管态,则执行update 9 */ 10 @Test 11 public void test8(){ 12 Student s1 = new Student();//临时态:没有OID,和session没有关系 13 s1.setName("test5"); 14 s1.setGender("male"); 15 s1.setBirthday(new Date()); 16 Session s = HibernateUtil.getSession(); 17 Transaction tx = s.beginTransaction(); 18 s.saveOrUpdate(s1);//持久态:有OID,和session有关系 19 tx.commit(); 20 s.close(); 21 } 22 @Test 23 public void test7(){ 24 Session s2 = HibernateUtil.getSession(); 25 Transaction tx2 = s2.beginTransaction(); 26 Student student2 = s2.get(Student.class, 2);//持久态 27 student2.setGender("male"); 28 s2.saveOrUpdate(student2);//把脱管态对象转成持久态 29 tx2.commit(); 30 s2.close(); 31 }
5、merge方法
update一个游离对象时,如果已经存在OID相同的持久态对象,则报错。可以使用merge合并,把游离对象的内容拷贝到内存中OID一样的对象的属性中
1 /* 2 * merge方法: 3 * 作用:合并两个对象。用脱管态对象的数据去替换持久态对象的数据。 4 */ 5 @Test 6 public void test6(){ 7 Session s1 = HibernateUtil.getSession(); 8 Transaction tx1 = s1.beginTransaction(); 9 Student studnet1 = s1.get(Student.class,2);//持久态 10 tx1.commit(); 11 s1.close(); 12 13 System.out.println(studnet1);//脱管态:有OID,和Session没有关系 14 15 Session s2 = HibernateUtil.getSession(); 16 Transaction tx2 = s2.beginTransaction(); 17 Student student2 = s2.get(Student.class, 2);//持久态 18 s2.merge(studnet1);//把脱管态对象转成持久态 19 tx2.commit(); 20 s2.close(); 21 }