前言
在没有系统学习Hibernate之前,并不知道在使用Hibernate之后,持久化对象会被区分为三种状态。我的“无知”导致了其实我并怎么会用Hibernate,也就不能在项目中“知人善用”。就像是当对象处于Persistent状态,修改他的属性时,将来调用Session.commit时,就会同步到数据库。修改完属性再调用update(),其实就是多此一举。下面我们就来看看这三种状态是怎么定义的,在代码中是如何区分的。
持久化对象
我们现在明确一下什么叫持久化对象,毕竟三种状态是用来区别持久化对象的。
【持久化对象】:指那些要存到数据库或硬盘中的内存中的对象。如:要转化成数据库中的记录的一些实体对象。
三种状态:
【Transient】(临时):对象没持久化到数据库中,也没被纳入到Session管理。
【Persistent】(持久):纳入到Session管理。
【Detached】(脱离):对象已经持久化到数据库中,但是没有被纳入Session管理。
说明:
有没有持久化到数据库很好理,就是该对象已经转化成了数据库表中的记录。
那什么叫做被纳入到Session管理呢?其实就是有没有被Session引用,我们知道Java的垃圾回收机制是,当一个内存中的对象没有其他引用它时,这样的对象就会在垃圾回收时,被视为垃圾,会从内存中清除。
如何确定是否被Session引用?
调用session.save(对象);session.update(对象)的对象,或是通过session.load()返回的对象,都是被Session引用的,都是持久化状态的对象。
看看代码就知道
public void testSave1() {
Session session = null;
Transaction tx = null;
User user = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
//Transient状态
user = new User();
user.setName("zhangsan");
user.setPassword("123");
user.setCreateTime(new Date());
user.setExpireTime(new Date());
session.save(user);
//id在sava完之后产生
//调用了save之后,user对象转变为Persistent状态
//Persistent状态的对象:当对象的属性发生改变的时候
//hibernate在清理缓存(脏数据检查)的时候,会和数据库同步
user.setName("lisi");
tx.commit();
//commit之后产生两条语句
//Hibernate: insert into User (name, password, createTime, expireTime, id) values (?, ?, ?, ?, ?)
//Hibernate: update User set name=?, password=?, createTime=?, expireTime=? where id=?
user.setName("wangwu");//仍是持久化状态的对象,但是还没有同步到数据库中
tx = session.beginTransaction();
tx.commit();//抛异常:org.hibernate.TransactionException: Transaction not successfully started
}catch(Exception e) {
e.printStackTrace();
if (tx != null) {
tx.rollback();
}
}finally {
HibernateUtils.closeSession(session);
}
//detached状态
user.setName("王五");
try {
session = HibernateUtils.getSession();
session.beginTransaction();
//将detached状态的对象重新纳入session管理
//此时将变为persistent状态的对象
//persistent状态的对象,在清理缓存是会和数据库同步
session.update(user);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
解释:
调用commit之后,对象被同步到数据库中。在commit之后,close之前,对象还是持久化状态,只是要再次同步到数据库,必须再调用commit方法,但是直接写这一句会抛异常,需要同时先开启事务,再commit才行。
此外:Persistent对象还可以通过get或load方法获得
public void testGet2() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
//get方法加载数据,如果不存在返回null
User user = (User)session.get(User.class, "54434343434343");
System.out.println(user.getName());
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
public void testLoad1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
User user = (User)session.load(User.class, "4028808125534a540125534b952e0001");
System.out.println(user.getName());
user.setName("王五");
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
总结
【1】.明确三种状态之间的区别:是否在数据库,是否在Session中
【2】.三种状态之间的转化:
【3】.在调用commit之后,对持久化对象做的任何修改就都同步到数据库了,所以必须要懂Hibernate哦,要不然,“轻轻一碰”对象,他就“冬眠”在数据库楼!