hibernate對象的三種狀態

hibernate對象具有三種狀態,即transient、persistent和detached

1.當我們通過Java的new關鍵字來生成一個實體對象時,這時這個實體對象就處於transient,其特點是:

(1) 不和 Session 實例關聯

(2) 在數據庫中沒有和瞬時對象關聯的記錄

2.persistent總是與 Session  Transaction 相關聯,在一個 Session 中,對持久對象的改變不會馬上對數據庫進行變更,而必須在 Transaction 終止,也就是執行 commit() 之後,纔在數據庫中真正運行 SQL 進行變更,持久對象的狀態纔會與數據庫進行同步。

transient轉爲persistent:

(1) 通過 Session  save()  saveOrUpdate() 方法把一個瞬時對象與數據庫相關聯,這個transient就成爲persistent

(2) 使用 fine(),get(),load()  iterater() 待方法查詢到的數據對象,將成爲persistent

persistent的特點:

(1)  Session 實例關聯

(2) 在數據庫中有和持久對象關聯的記錄

3.當session關閉後,對象就不處於Hibernate的緩存管理之中了,但是此時在數據庫中還存在一條與該對象對應的數據記錄,所以此時對象處於detached

persistent關聯的 Session 被關閉後,對象就變爲detached。對detached的引用依然有效,對象可繼續被修改。

detached特點:

(1) 本質上和transient相同

(2) 只是比transient多了一個數據庫記錄標識值 id.

persistent轉爲detached

當執行 close()  clear(),evict() 之後,persistent會變爲detached

detached轉爲persistent

通過 Session  update(),saveOrUpdate()  lock() 等方法,把detached變爲persistent

4.代碼驗證

仍然使用之前的Teacher

package com.baosight.model;

import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.SequenceGenerator;
import javax.persistence.TableGenerator;

/**
 * <p>Title: </p>
 * <p>Description:Teacher </p>
 * <p>Company: </p> 
 * @author yuan 
 * @date 2016-4-10 下午12:32:46*/
@Entity
@TableGenerator(name="tableGEN",table="table_gen",pkColumnName="pk_key",valueColumnName="pk_value",pkColumnValue="teacher",allocationSize=1)
@SequenceGenerator(name="teacherSEQ",sequenceName="teacherSEQ_DB")
//@IdClass(value=TeacherPK.class)
public class Teacher {
	private String id;
	private String name;
	private String title;
	//private TeacherPK pk;
	@Id
	@GeneratedValue//auto
//	@GeneratedValue(strategy=GenerationType.TABLE,generator="tableGEN")
//	@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="teacherSEQ")
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
//	@Id
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
//	@EmbeddedId
//	@Id
	/*public TeacherPK getPk() {
		return pk;
	}
	public void setPk(TeacherPK pk) {
		this.pk = pk;
	}*/
	
}
JUnit測試類TeacherTest.java

package com.baosight.model;

import static org.junit.Assert.*;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 * <p>Title:TecherTest </p>
 * <p>Description:TODO </p>
 * <p>Company: </p> 
 * @author yuan 
 * @date 2016-4-13 下午10:32:17*/
public class TeacherTest {
	private static SessionFactory sf = null;
	@BeforeClass
	public static void beforeClass(){
		// 讀取配置文件
		Configuration cfg = new AnnotationConfiguration();
		// 得到session工廠
		sf = cfg.configure().buildSessionFactory();
	}
	@Test
	public void testSave() {
		// 教師測試類
		Teacher t = new Teacher();
		t.setName("t1");
		t.setTitle("中級");

		System.out.println("transient狀態下id============="+t.getId());
		// 得到session
		Session session = sf.openSession();
		// 開啓事務
		session.beginTransaction();
		// session執行save
		session.save(t);
		System.out.println("persistent狀態下id============="+t.getId());
		// 事務提交
		session.getTransaction().commit();
		// 關閉session
		session.close();
		System.out.println("ditached狀態下id============="+t.getId());
	}
	@Test
	public void testDelete() {
		// 教師測試類
		Teacher t = new Teacher();
		t.setName("t1");
		t.setTitle("中級");
		
		System.out.println("transient狀態下id============="+t.getId());
		// 得到session
		Session session = sf.getCurrentSession();
		// 開啓事務
		session.beginTransaction();
		// session執行save
		session.save(t);
		System.out.println("persistent狀態下id============="+t.getId());
		// 事務提交
		session.getTransaction().commit();
		// 關閉session
		System.out.println("ditached狀態下id============="+t.getId());
		//刪除
		Session session2 = sf.getCurrentSession();
		// 開啓事務
		session2.beginTransaction();
		// session執行
		session2.delete(t);
		System.out.println("persistent狀態下id============="+t.getId());
		// 事務提交
		session2.getTransaction().commit();
		// 關閉session
		System.out.println("ditached狀態下id============="+t.getId());
	}
	@Test
	public void testDelete2() {
		// 教師測試類
		Teacher t = new Teacher();
		t.setId("24");
		
		System.out.println("transient狀態下id============="+t.getId());
		//刪除
		Session session2 = sf.getCurrentSession();
		// 開啓事務
		session2.beginTransaction();
		// session執行
		session2.delete(t);
		System.out.println("persistent狀態下id============="+t.getId());
		// 事務提交
		session2.getTransaction().commit();
		// 關閉session
		System.out.println("ditached狀態下id============="+t.getId());
	}
	@Test
	public void testLoad() {
		//使用代理,只有使用到查詢對象時纔會打印sql
		Session session = sf.getCurrentSession();
		// 開啓事務
		session.beginTransaction();
		// session執行
		Teacher t = (Teacher) session.load(Teacher.class, "1");
		//打印代理對象名稱
		System.out.println(t.getClass().getName());
//		System.out.println(t);
//		System.out.println("id============="+t.getId());
		// 事務提交
		session.getTransaction().commit();
		// 關閉session
//		System.out.println("id============="+t.getId());
	}
	@Test
	public void testGet() {
		//直接從數據庫查詢,會打印sql
		Session session = sf.getCurrentSession();
		// 開啓事務
		session.beginTransaction();
		// session執行
		Teacher t = (Teacher) session.get(Teacher.class, "1");
		System.out.println(t.getClass().getName());
//		System.out.println(t);
//		System.out.println("id============="+t.getId());
		// 事務提交
		session.getTransaction().commit();
		// 關閉session
//		System.out.println("id============="+t.getId());
	}
	@AfterClass
	public static void afterClass(){
		// 關閉session工廠
		sf.close();
	}
}
使用save方法驗證,執行testSave,結果爲:


使用save和delete方法驗證,執行testDelete,結果爲:


使用delete方法驗證,執行testDelete2,結果爲:


使用load方法驗證,執行testLoad,結果爲:


使用get方法驗證,執行testGet,結果爲:


5.hibernate對象三種狀態的圖形表示



以上即爲hibernate對象三種狀態的相關內容,這是hibernate提供的Session接口各種用法的內在原理,需要好好理解。

發佈了50 篇原創文章 · 獲贊 46 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章