一、hibernate的三种状态讲解
transient(瞬时)状态表示刚刚new出来一个对象,但还没有在数据库中保存。
不处于Session的缓存中。
persistent(持久化)状态表示在数据库里面存在着该对象的一条记录。
当调用session.save()时就变成持久化状态。
detached(离线)状态表示数据库中有记录,但不在session的中。
关闭session时候
二、拷贝上个项目。
在org.zttc.itat.test包下新建Junit测试类
TestStatus.java
package org.zttc.itat.test;
import java.text.SimpleDateFormat;
import org.hibernate.Session;
import org.junit.Test;
import org.zttc.itat.model.User;
import org.zttc.itat.util.HibernateUtil;
public class TestStatus {
private static final SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
@Test
public void testTransient() {
Session session=null;
try {
session=HibernateUtil.openSession();
session.beginTransaction();
User u=new User();
u.setNickname("张小三");
u.setPassword("123");
u.setUsername("zhangsan");
u.setBorn(sdf.parse("1999-11-11"));
//以上u就是Transient状态,表示没有被session管理而且数据库中没有。
//当执行了save之后,u被session所管理,而且数据库中会存在,就为persistent状态。
session.save(u);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if(session!=null) session.getTransaction().rollback();
} finally{
HibernateUtil.close(session);
}
}
@Test
public void testPersistent01() {
Session session=null;
try {
session=HibernateUtil.openSession();
session.beginTransaction();
User u=new User();
u.setNickname("赵小三");
u.setPassword("828");
u.setUsername("xiaozhao");
u.setBorn(sdf.parse("1988-11-18"));
//以上u就是Transient状态,表示没有被session管理而且数据库中没有。
//当执行了save之后,u被session所管理,而且数据库中会存在,就为persistent状态。
session.save(u);
/*
* 此时u是持久化状态,已经被session所管理,当在提交时,即执行session.getTransaction().commit()语句,
* 会把session中的u和目前的u所比较。
* 如果两个u不一样,会继续发出相应的sql语句。
*/
u.setNickname("赵老三");
/*
* 此时会发出两条sql语句:一条用来插入,一条用来更新。
* Hibernate: insert into t_user (username, password, nickname, born) values (?, ?, ?, ?)
* Hibernate: update t_user set username=?, password=?, nickname=?, born=? where id=?
*/
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if(session!=null) session.getTransaction().rollback();
} finally{
HibernateUtil.close(session);
}
}
@Test
public void testPersistent02() {
/*
* 会发出几条sql语句,执行结果是什么?
*
*/
Session session=null;
try {
session=HibernateUtil.openSession();
session.beginTransaction();
User u=new User();
u.setNickname("赵晓八");
u.setPassword("009");
u.setUsername("zxj");
u.setBorn(sdf.parse("1976-1-5"));
//执行save时候会发出insert语句。
session.save(u);
u.setPassword("222");
//这条save语句没用
session.save(u);
u.setNickname("赵三碰");
//没有用
session.update(u);
u.setBorn(sdf.parse("1999-9-9"));
//没有用,只有在commit并且对象不一样的时候才执行update语句
session.update(u);
session.getTransaction().commit();
/*
* 会发出两条sql语句:
* Hibernate: insert into t_user (username, password, nickname, born) values (?, ?, ?, ?)
* Hibernate: update t_user set username=?, password=?, nickname=?, born=? where id=?
* 因为,执行save之后,处于持久化状态,session的所有操作都没用,
* 只有在session提交的时候会比较save之前的u和save之后的u是否改变,然后发出相应的sql语句。
*/
} catch (Exception e) {
e.printStackTrace();
if(session!=null) session.getTransaction().rollback();
} finally{
HibernateUtil.close(session);
}
}
@Test
public void testPersistent03() {
Session session=null;
try {
session=HibernateUtil.openSession();
session.beginTransaction();
User u=new User();
u.setNickname("刘晓八");
u.setPassword("009");
u.setUsername("zxj");
u.setBorn(sdf.parse("1976-1-5"));
session.save(u);
//一下三条语句没有用
session.save(u);
session.update(u);
session.update(u);
session.getTransaction().commit();
/*
* 只会发一条sql语句,因为save前的u和save后commit之前的u一样。
*/
} catch (Exception e) {
e.printStackTrace();
if(session!=null) session.getTransaction().rollback();
} finally{
HibernateUtil.close(session);
}
}
@Test
public void testPersistent04() {
Session session=null;
try {
session=HibernateUtil.openSession();
session.beginTransaction();
//此时u是Persistent状态。因为u被session所管理了。
User u=(User)session.load(User.class, 6);
u.setUsername("aaa");
session.getTransaction().commit();
/*
* 此时会发两条sql语句,一条select,一条update。因为session中的u对象变化了。
*/
} catch (Exception e) {
e.printStackTrace();
if(session!=null) session.getTransaction().rollback();
} finally{
HibernateUtil.close(session);
}
}
@Test
public void testPersistent05() {
Session session=null;
try {
session=HibernateUtil.openSession();
session.beginTransaction();
//此时u是Persistent状态。因为u被session所管理了。
User u=(User)session.load(User.class, 6);
session.getTransaction().commit();
u.setNickname("123");
/*
* 此时发出1条sql语句select,因为commit已经执行完成了。
* 此时u还是Persistent状态。
*/
} catch (Exception e) {
e.printStackTrace();
if(session!=null) session.getTransaction().rollback();
} finally{
HibernateUtil.close(session);
}
}
@Test
public void testPersistent06() {
Session session=null;
try {
session=HibernateUtil.openSession();
session.beginTransaction();
//此时u是Persistent状态。因为u被session所管理了。
User u=(User)session.load(User.class, 6);
session.getTransaction().commit();
//commit结束后,下面的u任然是Persistent状态。
u.setNickname("123");
session.beginTransaction();
session.getTransaction().commit();
/*
* 会发两条sql语句
*/
} catch (Exception e) {
e.printStackTrace();
if(session!=null) session.getTransaction().rollback();
} finally{
HibernateUtil.close(session);
}
}
@Test
public void testDetached01() {
Session session=null;
try {
session=HibernateUtil.openSession();
session.beginTransaction();
User u =new User();
u.setId(6);
/*
* 此时u没有被session管理,是离线(detached)状态。注意和瞬时状态比较。
*/
u.setNickname("juke");
//当执行save的时候总会添加一条数据。此时id会根据Hibernate所定义的规则生成。
//因为id为6的已经存在,所以会开辟一个新的id为7的数据。
session.save(u);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if(session!=null) session.getTransaction().rollback();
} finally{
HibernateUtil.close(session);
}
}
@Test
public void testDetached02() {
Session session=null;
try {
session=HibernateUtil.openSession();
session.beginTransaction();
User u =new User();
u.setId(6);
session.update(u);
session.getTransaction().commit();
//这时候u会变成持久化状态,数据库中id为6的记录全变为空,因为其它值为空,即
//username、nickname等等为空。
} catch (Exception e) {
e.printStackTrace();
if(session!=null) session.getTransaction().rollback();
} finally{
HibernateUtil.close(session);
}
}
@Test
public void testDetached022() {
Session session=null;
try {
session=HibernateUtil.openSession();
session.beginTransaction();
User u =new User();
u.setId(6);
session.update(u);
u.setBorn(sdf.parse("1921-1-1"));
u.setNickname("bo");
u.setPassword("hello");
session.update(u);
session.getTransaction().commit();
/*
* 此时会发出1条sql语句并把id为6的记录更新。
*/
} catch (Exception e) {
e.printStackTrace();
if(session!=null) session.getTransaction().rollback();
} finally{
HibernateUtil.close(session);
}
}
@Test
public void testDetached03() {
Session session=null;
try {
session=HibernateUtil.openSession();
session.beginTransaction();
User u =new User();
u.setId(6);
session.update(u);
u.setBorn(sdf.parse("1921-1-1"));
u.setNickname("bo");
u.setPassword("hello");
/*
* 把id更改了,会报错,如下。
* identifier of an instance of org.zttc.itat.model.User was altered from 6 to 90
*id为8的u是瞬时的,不存在于数据库中。虽然数据库中id为8有记录。但是下面这个
*id为8的u是新的,是瞬时的,和数据库中的不一样。
*/
u.setId(8);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if(session!=null) session.getTransaction().rollback();
} finally{
HibernateUtil.close(session);
}
}
@Test
public void testDetached04() {
Session session=null;
try {
session=HibernateUtil.openSession();
session.beginTransaction();
User u =new User();
u.setId(6);
session.delete(u);
//执行完delete后u就是Transient对象。
u.setNickname("bbb");//瞬时对象u不会被session管理,数据库中也不存在。所以这句话没用。
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if(session!=null) session.getTransaction().rollback();
} finally{
HibernateUtil.close(session);
}
}
@Test
public void testDetached05() {
Session session=null;
try {
session=HibernateUtil.openSession();
session.beginTransaction();
User u =new User();
u.setNickname("juke");
session.update(u);
/*
* u是瞬时状态,瞬时状态在数据库中没有数据,执行update会报错。
*/
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if(session!=null) session.getTransaction().rollback();
} finally{
HibernateUtil.close(session);
}
}
@Test
public void testDetached051() {
Session session=null;
try {
session=HibernateUtil.openSession();
session.beginTransaction();
User u =new User();
u.setId(7);
u.setNickname("juke");
session.saveOrUpdate(u);
/*
* saveOrUpdate意思是:u是离线状态,会执行update。u是瞬时状态会执行save。
* 因为有setId,所以是离线状态,会执行update。
*/
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if(session!=null) session.getTransaction().rollback();
} finally{
HibernateUtil.close(session);
}
}
@Test
public void testDetached06() {
Session session=null;
try {
session=HibernateUtil.openSession();
session.beginTransaction();
//u1是Persistent状态
User u1 =(User) session.load(User.class, 7);
System.out.println(u1.getUsername());
//u2没有被session管理,而且在数据库中存在这样的id,所以是detached状态。
User u2=new User();
u2.setId(7);
u2.setPassword("2225555");
/*
* 当执行下面语句时候u2变成Persistent状态,这时候在session中就会存在两份相同的对象,会报错。
* 但是把下面这句话换成session.merge(u2)就行了,因为merge会判断
* session中是否存在两份相同的对象如果存在,会把它们合并。
* 但是merge方法一般不用。
*/
session.saveOrUpdate(u2); //session.merge(u2);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if(session!=null) session.getTransaction().rollback();
} finally{
HibernateUtil.close(session);
}
}
@Test
public void testClear() {
Session session=null;
try {
session=HibernateUtil.openSession();
session.beginTransaction();
User u =(User) session.load(User.class, 7);
u.setNickname("zhan");
//清空session后,Persistent对象不存在。不会发update语句,数据库也不会变化。
session.clear();
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if(session!=null) session.getTransaction().rollback();
} finally{
HibernateUtil.close(session);
}
}
}