天天看点

hibernate持久化对象的三种状态

hibernate的准备及配置工作参见我的另一篇文章(该文章中介绍hibernate的搭建及简单配置) : http://ysj5125094.iteye.com/blog/1893871

下面的实现类是用JUnit测试的,如果想了解JUnit内容请参见我的另一篇文章: http://ysj5125094.iteye.com/blog/1897295

持久化对象的状态:

1.瞬时对象(Transient Objects):使用new 操作符初始化的对象不是立刻就持久的。它们的状态是瞬时的,也就是说它们没有任何跟数据表相关联的行为,只要应用不再引用这些对象(不再被任何其它对象所引用),它们的状态将会丢失,并由垃圾回收机制回收。

2.持久化对象(Persist Objects):持久实例是任何具有数据库标识的实例。它有持久化管理器Session统一管理,持久实例是在事务中进行操作的。它们的状态在事务结束时同数据库进行同步。当事务提交时,通过执行SQL的insert、update和delete语句把内存中的状态同步到数据库中。

3.离线对象(Detached Objects):Session关闭之后,持久化对象就变为离线对象。离线表示这个对象不能再与数据库保持同步,它们不再受Hibernate管理。

下面通过一个小例子来具体说明持久化对象的生命周期:

为了方便,先创建一个管理Session的工具类HibernateUtils.java,代码如下:

package com.ysj.utils;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;


public class HibernateUtils {
	
	/**
	 * 创建静态块,用于初始化SessionFactory
	 */
	private static SessionFactory factory ;
	static{
		try{
			// 默认获取src根目录下的 hibernate.cfg.xml配置文件
			Configuration cfg = new Configuration().configure();
			// 通过配置文件获取 sessionFactory
			factory = cfg.buildSessionFactory() ; 
		}catch(Exception e){
			e.printStackTrace() ;
		}
	}
	
	/**
	 * 获得SessionFactory
	 */
	public static SessionFactory getSessionFactory(){
		return factory ;
	}
	
	/**
	 * 获得Session
	 */
	public static Session getSession(){
		if(factory != null){
			return factory.openSession() ;
		}else{
			return null ;
		}
	}
	
	/**
	 * 关闭Session
	 */
	public static void closeSession(Session session){
		if(session != null){
			if(session.isOpen()){
				session.close() ;
				session = null ;
			}
		}
	}
}
           

测试类SessionTest.java,代码如下:

package com.ysj;

import java.util.Date;

import junit.framework.TestCase;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.ysj.utils.HibernateUtils;

public class SessionTest extends TestCase {
	
	/**
	 * 持久化对象生命周期的过程演示
	 */
	public void testSave(){
		Session session = null ;
		Transaction tran = null ;
		User user = null ;
		try{
			session = HibernateUtils.getSession() ;
			tran = session.beginTransaction() ;
			/**
			 * Transient(瞬态) :
			 * 1、在数据库中没有与之匹配的数据;
			 * 2、没有纳入session的管理;
			 * 3、如果在瞬态session 调用了 save()等方法就变为了持久态;
			 */  
			user = new User() ;
			user.setName("小一") ;
			user.setPassword("xiaoyi") ;
			user.setCreateTime(new Date()) ;
			user.setExpireTime(new Date()) ;
			/**
			 * Persistent(持久态) :
			 * 1、persistent状态的对象在数据库中有与之匹配的数据;
			 * 2、纳入了session的管理;
			 * 3、在清理缓存(脏数据检查)的时候,会和数据库同步;
			 * 4、在session关闭后,在持久态里面的内容,变为托管态,数据如果修改不会影响数据库对应值;
			 */
			session.save(user);
			
			user.setName("小二");
			/*
			 * 注意 :
			 * 在执行完tran.commit()方法后,会在控制台输出两条SQL语句,分别是
			 * Hibernate: insert into t_user (name, password, createTime, expireTime, id) values (?, ?, ?, ?, ?)
			 * Hibernate: update t_user set name=?, password=?, createTime=?, expireTime=? where id=?
			 * 
			 * session.save(user); // 执行到save()方法时插入数据库一条记录。
			 * user.setName("小二"); // 当对持久态对象进行修改时,会执行update操作。相当于在该条词句下面显示执行session.update(user);操作。 
			 */
			tran.commit() ;
			
		}catch(Exception e){
			if(tran != null){
				tran.rollback() ;
			}
			e.printStackTrace() ;
		}finally{
			HibernateUtils.closeSession(session);
		}
		/**
		 * Detached(托管态) :
		 * 1、在数据库中有与之匹配的数据;
		 * 2、没有纳入session的管理;
		 * 3、托管态对象中有主键值,瞬态的id没有主键值
		 */
		user.setName("小三") ;
		try{
			session = HibernateUtils.getSession() ;
			session.beginTransaction() ;
			/*
			 * 将detached对象重新纳入session管理,此时将变为persistent状态的对象。
			 * persistent状态的对象,在清理缓存时会和数据库同步。
			 */
			session.update(user);
			session.getTransaction().commit() ;
		}catch(Exception e){
			session.getTransaction().rollback();
			e.printStackTrace();
		}finally{
			HibernateUtils.closeSession(session);
		}
	}
}
           

附件中存放的是用MyEclipse6.0的File System导出的练习工程,有需要的可以直接下载解压导入进行测试.

附件内容包括:save,get,load,query,JUnit的练习和生命周期的介绍。下载后先读readme.txt。

继续阅读