天天看點

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。

繼續閱讀