Hibernate學習(4)- Hibernate對象的生命週期

一、Hibernate對象的生命週期(瞬時狀態、持久化狀態、遊離狀態)

一、瞬時狀態(Transient):
  使用new操做符初始化的對象就是瞬時狀態,沒有跟任何數據庫數據相關聯;
二、持久化狀態(Parsistent):
  若是對象與Session對象關聯起來,且該對象對應到數據庫記錄,則稱該對象處於持久化狀態。
三、遊離狀態(Detached)
  Session被關閉或調用了Session的evict或clear方法把它從Session中移除了,則該對象脫離了Session的管理,持久化狀態變成遊離狀態,這表示該對象不在和數據庫保持同步,不受hibernate管理。html

二、三種狀態的比較

Transient:瞬時狀態的對象只存在於內存中。
Parsistent:持久狀態的對象分別存在於內存、session對象、數據庫之中。
Detached:遊離狀態的對象存在於內存、數據庫之中,但不在session對象中。java

三、三種狀態之間的轉換

一、轉化路徑詳解

1)瞬時對象(Transient)git

  new 建立 (無->Transient) ,即:對象經過構造方法成爲瞬時態;github

2)持久對象(Persistent)sql

  1.1)get/load (無->Persistent),即:對象能夠由session的load或get方法直接成爲持久態;數據庫

    get經過類名和id從數據庫讀取指定記錄,無匹配記錄返回null。
    load經過類名和id從數據庫讀取指定記錄,無匹配記錄拋ObjectNotException異常。緩存

  1.2)save/saveOrUpdate/persist (Transient->Persistent) ,即:瞬時態對象能夠經過save,saveOrUpdate或persist方法成爲持久態;session

  1.3)update/saveOrUpdate(Detached->Persistent),即:遊離態對象則能夠經過update,saveOrUpdate成爲持久態;工具

3)遊離對象(Detached)spa

  遊離態只能由持久態轉換而來(Persistent->Detached),經過close、clear、evict方法實現。

  evict--把某個對象從session中移除,變爲遊離態;
  clear--把全部對象從session中移除,對象所有變爲遊離態;
  close--關閉session,其中的對象所有變爲遊離態;

二、幾種方法的詳解

一、get 與 load

  都是從數據庫中加載數據封裝爲java對象,直接變爲持久態;

二、save,update與saveOrUpdate

  save是將瞬時態轉爲持久態;
  update是將遊離態轉爲持久態;
  saveOrUpdate能夠說是二者的綜合,它執行時先判斷對象的狀態(主要是經過有無主鍵判斷的),如果自由態,則save,如果遊離態,則update;

三、save與persist

  二者都是將對象由瞬時態轉爲持久態,但返回值不一樣:save返回主鍵值,而persist不返回;

 四、實例,詳見註解狀態(封裝的工具類詳見Demo)

package com.demo.test;

import org.hibernate.Session;
import org.junit.Test;

import com.demo.Utils.HibernateUtil;
import com.demo.pojo.User;

public class SessionTest {

    @Test
    public void saveTest() {
        Session session = null;
        User user = null;
        try {
            session = HibernateUtil.currentSession();
            session.beginTransaction();
            //建立瞬時狀態對象
            user = new User();
            user.setName("東方不敗");
            user.setPwd("123456");
            //user還是一個瞬態對象
            
            //持久狀態,user被session管理,而且id有值   -- oid
            //此時user已變成 持久態對象
            session.save(user);
            
            //在持久狀態下髒數據檢查:當提交事務,清理緩存時發現session中的數據與數據庫的數據不一致時,會把session的數據更新到數據庫
            //保存之後,再修改對象,會產生多條sql語句,效率下降,因此在save前修改數據
            user.setName("西方求敗");
            session.getTransaction().commit();        
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            HibernateUtil.closeSession();
        }
        //close、clear、evict方法都會使持久態對象  變成 遊離狀態 -- user
        user.setName("令狐沖");

        try {
            session = HibernateUtil.currentSession();
            session.beginTransaction();
            //update使對象變成 持久狀態
            session.update(user);
            session.getTransaction().commit();        
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            HibernateUtil.closeSession();
        }
    }
    
    @Test
    public void getTest() {
        Session session = null;
        try {
            session = HibernateUtil.currentSession();
            //get後變爲持久狀態
            //get方法會當即查詢該對象:範圍(查詢不到去下一級查詢)從session -> sessionFactory ->數據庫
            //get方法找不到對象,不會有異常,返回nul
            User user = session.get(User.class, 7L);
            System.out.println(user.toString());
            
            User user2 = session.get(User.class, 17L);
            System.out.println(user2);
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            HibernateUtil.closeSession();
        }
    }
    
    @Test
    public void loadTest() {
        Session session = null;
        try {
            session = HibernateUtil.currentSession();
            //load後變爲持久狀態(這裏加載機制與get不一樣,稍後我會單獨寫一篇文章 介紹 get與load 的區別)
            //對象不存在時,拋出異常
            User user = session.load(User.class, 7L);
            System.out.println(user.toString());
            
            User user2 = session.load(User.class, 17L);
            System.out.println(user2.toString());
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            HibernateUtil.closeSession();
        }
    }
    
    @Test
    public void clearTest() {
        Session session = null;
        User user = null;
        try {
            session = HibernateUtil.currentSession();
            session.beginTransaction();
            user = session.get(User.class,7L);
            System.out.println(user.getName());
            session.getTransaction().commit();    
            session.clear();
            //遊離狀態,不被session管理,數據庫不會被更改
            user.setName("任我行");
            System.out.println(user.getName());
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            HibernateUtil.closeSession();
        }
    }
    
    @Test
    public void updateTest() {
        Session session = null;
        User user = null;
        try {
            session = HibernateUtil.currentSession();
            session.beginTransaction();
            //瞬時狀態
            //手動構造對象 也能夠修改,可是須要指定全部的屬性值,不然,不設置的對象會置空,不建議這樣update數據
            /*user = new User();
            user.setId(7L);
            user.setName("盈盈");
            session.update(user);*/
            //通常這樣修改
            //先去查詢
            user = session.get(User.class,7L);
            if(user != null) {
                user.setName("盈盈");
                session.update(user);
            }
            session.getTransaction().commit();    
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            HibernateUtil.closeSession();
        }
    }
    
    @Test
    public void deleteTest() {
        Session session = null;
        User user = null;
        try {
            session = HibernateUtil.currentSession();
            session.beginTransaction();
            //瞬時狀態
            //手動構造一個對象,指定主鍵是能夠刪除數據的,不建議這樣搞
            /*user = new User();
            user.setId(7L);
            session.delete(user);*/
            //應該這樣刪除數據
            //從數據先加載該對象,而後刪除,能夠避免異常
            user = session.get(User.class, 7L);
            if(user != null) {
                session.delete(user);
            }
            session.getTransaction().commit();    
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            HibernateUtil.closeSession();
        }
    }
    
    
}

 

 

PS:源碼地址   https://github.com/JsonShare/hibernate-demo

 

PS:原文地址  http://www.cnblogs.com/JsonShare/p/8686078.html

相關文章
相關標籤/搜索