Java实战之02Hibernate-03Session中的常用方法

时间:2022-03-05 11:34:44

九、Session中的常用方法

1、save方法

都是临时态————>持久态

2、persist方法

作用:

持久化临时态对象。

与save方法的区别:

开始了事务:persist和save没有区别。

不开启事务:

persist:什么都不会做。

save:

hibernate3:计划保存数据,因为没有开启事务,自动回滚。

hibernate5:提供一个内置事务执行保存操作。

 /*
* save方法和persist方法
* 共同点:
* 都是把临时态对象转成持久态
* 区别:
* 1、提供者不一样
* save方法是hibernate提供的
* persist方法是JPA规范提供的 Java Persistence API
* 2、在没有事务的支持下
* save方法:
* hibernate5:会用框架内置的事务执行保存操作。
* hibernate3:就会执行保存,但是没有明确的提交操作,在超时后,事务自动回滚。
* persist方法:
* 什么都不去做。
*
*/
@Test
public void test2(){
Student s1 = new Student();//临时态
s1.setName("test3");
s1.setGender("female");
s1.setBirthday(new Date()); Session s = HibernateUtil.getSession();
//Transaction tx = s.beginTransaction();
s.persist(s1);//持久态
//tx.commit();
s.close();
} @Test
public void test1(){
Student s1 = new Student();//临时态:没有OID,和session没有关系
s1.setName("test4");
s1.setGender("male");
s1.setBirthday(new Date()); Session s = HibernateUtil.getSession();
Transaction tx = s.beginTransaction();
s.save(s1);//持久态:有OID,和session有关系
tx.commit();
s.close();
}

3、update方法

把脱管态-------->持久态

3.1、若脱管态对象的属性没有发生变化,也会执行update语句。可以在<class select-before-update="true">改变。开发中可以对于属性不经常变化的实体做此配置

Java实战之02Hibernate-03Session中的常用方法

解决问题:

Java实战之02Hibernate-03Session中的常用方法

3.2、update一个脱管态对象时,如果已经存在OID相同的持久态对象,则报错

Java实战之02Hibernate-03Session中的常用方法

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方法

作用:保存或修改

临时态————>持久态:保存

Java实战之02Hibernate-03Session中的常用方法

脱管态————>持久态:更新

Java实战之02Hibernate-03Session中的常用方法

依据对象的状态来确定save还是update

特殊情况:

当在对象的映射xml文件中,<id中设置了unsaved-value>,且和OID保持一致时,就不再把对象看成游离态而是临时态。

Java实战之02Hibernate-03Session中的常用方法

Java实战之02Hibernate-03Session中的常用方法

 /*
* saveOrUpdate
* 作用:
* 执行保存或者更新
* 执行依据:
* 依据的是对象的状态。
* 如果对象是临时态,则执行save
* 如果对象是脱管态,则执行update
*/
@Test
public void test8(){
Student s1 = new Student();//临时态:没有OID,和session没有关系
s1.setName("test5");
s1.setGender("male");
s1.setBirthday(new Date());
Session s = HibernateUtil.getSession();
Transaction tx = s.beginTransaction();
s.saveOrUpdate(s1);//持久态:有OID,和session有关系
tx.commit();
s.close();
}
@Test
public void test7(){
Session s2 = HibernateUtil.getSession();
Transaction tx2 = s2.beginTransaction();
Student student2 = s2.get(Student.class, 2);//持久态
student2.setGender("male");
s2.saveOrUpdate(student2);//把脱管态对象转成持久态
tx2.commit();
s2.close();
}

5、merge方法

update一个游离对象时,如果已经存在OID相同的持久态对象,则报错。可以使用merge合并,把游离对象的内容拷贝到内存中OID一样的对象的属性中

Java实战之02Hibernate-03Session中的常用方法

 /*
* merge方法:
* 作用:合并两个对象。用脱管态对象的数据去替换持久态对象的数据。
*/
@Test
public void test6(){
Session s1 = HibernateUtil.getSession();
Transaction tx1 = s1.beginTransaction();
Student studnet1 = s1.get(Student.class,2);//持久态
tx1.commit();
s1.close(); System.out.println(studnet1);//脱管态:有OID,和Session没有关系 Session s2 = HibernateUtil.getSession();
Transaction tx2 = s2.beginTransaction();
Student student2 = s2.get(Student.class, 2);//持久态
s2.merge(studnet1);//把脱管态对象转成持久态
tx2.commit();
s2.close();
}