1. 程式人生 > >hibernate框架學習筆記5:緩存

hibernate框架學習筆記5:緩存

很好 close nts oid img 關閉資源 次方 兩個 res

緩存不止存在與程序中,電腦硬件乃至於生活中都存在緩存

目的:提高效率

比如IO流讀寫字節,如果沒有緩存,讀一字節寫一字節,效率低下

hibernate中的一級緩存:提高操作數據庫的效率

示例:

抽取的工具類

技術分享圖片
package utils;

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

public class HibernateUtils {
    private static SessionFactory sf;
    
    
static{ //1 創建,調用空參構造 Configuration conf = new Configuration().configure(); //2 根據配置信息,創建 SessionFactory對象 sf = conf.buildSessionFactory(); } //獲得session => 獲得全新session public static Session openSession(){ //3 獲得session Session session = sf.openSession();
return session; } //獲得session => 獲得與線程綁定的session public static Session getCurrentSession(){ //3 獲得session Session session = sf.getCurrentSession(); return session; } }
View Code

測試類:

示例1:

package cache;

import org.hibernate.Session;
import
org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.junit.Test; import domain.Customer; import utils.HibernateUtils; //測試一級緩存 public class Demo { @Test //證明一級緩存存在 public void fun1(){ //1 獲得session Session session = HibernateUtils.openSession(); //2 控制事務 Transaction tx = session.beginTransaction(); //3執行操作 Customer c1 = session.get(Customer.class, 1l); Customer c2 = session.get(Customer.class, 1l); Customer c3 = session.get(Customer.class, 1l); Customer c4 = session.get(Customer.class, 1l); Customer c5 = session.get(Customer.class, 1l); System.out.println(c3==c5);//true //4提交事務.關閉資源 tx.commit(); session.close();// 遊離|托管 狀態, 有id , 沒有關聯 //結果(保證數據庫中存在主鍵為1的數據): //這裏調用了五次方法,但是只打印一次SQL語句 } }

原理:程序第一次調用get方法,hibernate發送SQL語句查詢數據庫,查詢結果以ResulySet對象返回,

hibernate再組裝成Customer(實體類對象),存入session緩存對象,對象返回給程序

第二次調用get方法,會先從緩存中查看是否存在id=1的Customer對象,如果有,直接返回緩存中的對象

多次調用原理相同

明顯地發現:這裏的緩存技術很好地提升了效率

示例2:

    @Test
    //
    public void fun2(){
        //1 獲得session
        Session session = HibernateUtils.openSession();
        //2 控制事務
        Transaction tx = session.beginTransaction();
        //3執行操作
        
        Customer c1 = session.get(Customer.class, 1l);
        
        c1.setCust_name("哈哈");//4提交事務.關閉資源
        tx.commit();
        session.close();// 遊離|托管 狀態, 有id , 沒有關聯
        
        
    }

引入了快照的概念

原理:

上邊的原理其實有省略,數據庫返回結果後,hibernate組裝的時候,其實組裝了兩個對象,

一個放入緩存中,一個放入快照,返回給程序的是緩存對象,程序第一次修改了緩存對象,事務提交,

這時候hibernate比較緩存中的對象和快照,如果有變化,會同步到數據庫中,沒有變化,什麽都不做

這裏就提高了效率,不會多次去數據庫查詢,只需要比對緩存中的對象,減少不必要地SQL查詢語句

示例3:

    @Test
    //持久化狀態對象其實就是放入session緩存中的對象
    public void fun3(){
        //1 獲得session
        Session session = HibernateUtils.openSession();
        //2 控制事務
        Transaction tx = session.beginTransaction();
        //3執行操作
        
        Customer c1 = new Customer();
        c1.setCust_id(1l);//托管|遊離
        
        session.update(c1);//c1被放入session緩存了
        
        
        Customer c2 = session.get(Customer.class, 1l);
        
        //4提交事務.關閉資源
        tx.commit();
        session.close();// 遊離|托管 狀態, 有id , 沒有關聯
        
        
    }

這段代碼運行中,打印SQL的UPDATE語句

原因:緩存中不存在快照,c1放入session緩存中對比快照時候必然不一致,而c2這一句調用get方法後,依照上邊的原理,才會運行SQL的UPDATE語句

所以,這段代碼中真正使hibernate發送SQL語句的是c2這一行

hibernate框架學習筆記5:緩存