在Hibernate框架中詳談一級緩存

来源:http://www.cnblogs.com/liujiayun/archive/2016/08/14/5769872.html
-Advertisement-
Play Games

在學習Hibernate的過程中我們肯定會碰上一個名詞 緩存,一直都聽說緩存機制是Hibernate中的一個難點,它分為好幾種,有一級緩存,二級緩存和查詢緩存 今天呢,我就跟大家分享分享我所理解的一級緩存 要想完美的體現出緩存機制的話,我想通過查詢語句生成的sql應該就能夠很清楚的看到 那些Hibe ...


在學習Hibernate的過程中我們肯定會碰上一個名詞---緩存,一直都聽說緩存機制是Hibernate中的一個難點,它分為好幾種,有一級緩存二級緩存查詢緩存

今天呢,我就跟大家分享分享我所理解的一級緩存

要想完美的體現出緩存機制的話,我想通過查詢語句生成的sql應該就能夠很清楚的看到

那些Hibernate的配置信息我就不展示了,直接看關鍵代碼

場景:我要查詢同一個對象,查詢兩次,觀察在不同的情況下,sql語句的生成情況

我事先準備了一個HibernateUtil工具類,具體如下

package util;

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

public class HibernateUtil {
    //初始化一個ThreadLocal對象
    private static final ThreadLocal sessionTL =new ThreadLocal();
    private static Configuration configuration;
    private final static SessionFactory sessionFactory;
    static {
        try{
            configuration=new Configuration().configure();
            sessionFactory=configuration.buildSessionFactory();
        }catch(Throwable ex){
            ex.printStackTrace();
            throw new ExceptionInInitializerError(ex);
        }
        
    }
    
    //獲取session
    public static Session currentSession(){
        Session session=(Session)sessionTL.get();
        if(session==null){
            session=sessionFactory.openSession();
            sessionTL.set(session);
        }
        return session;
    }
    
    //關閉session
    public static void closeSession(){
        Session session= (Session)sessionTL.get();
        sessionTL.set(null);
        session.close();
     }
}

 

正常我們訪問DB端時應該是訪問幾次就發送幾次sql,如下所示

    //查詢學生信息
    public static void select(){
        
        //由班級查詢該班級學生信息
        Session session=HibernateUtil.currentSession();
        Grade grade=(Grade) session.get(Grade.class, 14);
        //輸出班級信息
        System.out.println(grade.getGname());
        Grade grade2=(Grade) session.get(Grade.class, 17);
        //輸出班級信息
        System.out.println(grade2.getGname());
    }

 

結果應該是這樣

 

那麼問題就來了,我們現在有如下幾個場景

場景一:使用同一個session連續查詢兩次同一個對象

//查詢學生信息
    public static void select(){
        
        //由班級查詢該班級學生信息
        Session session=HibernateUtil.currentSession();
        Grade grade=(Grade) session.get(Grade.class, 14);
        //輸出班級信息
        System.out.println(grade.getGname());
        Grade grade2=(Grade) session.get(Grade.class, 14);
        //輸出班級信息
        System.out.println(grade2.getGname());
    }

 

這個時候我們不難發現,此時我查詢的是同一個對象,按照正常理解,我查詢了兩遍應該向DB端發送兩條sql語句才對,下麵看看實際的sql數

這個時候可能有的小伙伴就有疑問了,我們後面再解釋這種情況,我們先接著看第二種場景

場景二:在第一次查詢完畢後,關閉session對象,重新開啟一個session然後繼續查詢同一個對象

//查詢學生信息
    public static void select(){
        
        //由班級查詢該班級學生信息
        Session session=HibernateUtil.currentSession();
        Grade grade=(Grade) session.get(Grade.class, 14);
        //輸出班級信息
        System.out.println(grade.getGname());
        //關閉session
        HibernateUtil.closeSession();
        //重新獲取session
        session=HibernateUtil.currentSession();
        Grade grade2=(Grade) session.get(Grade.class, 14);
        //輸出班級信息
        System.out.println(grade2.getGname());
    }

 

這個時候我們查詢的任然是同一個對象,結果卻如下圖

那麼,通過以上兩個場景的模擬,有些小伙伴可能已經明白是怎麼回事了,可能有些小伙伴們還有些迷糊,下麵我就講講我的看法吧~

總結:1:當我沒有關閉session時用的同一個session兩次訪問同一個對象時,只會向DB端發送一條sql語句
    * 原因:因為我第一次訪問資料庫的時候Hibernate會自動的將我查詢出來的結果保留一份查詢出來的對象到一級緩存
          並且這個額對象是根據OID唯一標識的,也可以理解為資料庫中的主鍵值,然後當我再一次訪問一個對象時,Hibernate
        機制會自動的先去一級緩存中查找看有沒有OID與我要查詢的OID相同的對象,如果有的話,則直接從一級緩存中 拿數據
          如果相同的OID則說明緩存中沒有我要的記錄,那麼就會直接去訪問DB端了,這樣的話,又會重新發送一條sql
    2:當我第一次查詢完數據後立即關閉session,這時重新開啟一個session來訪問同一個對象,這時我們會發現它居然向資料庫發送了兩條Sql語句。這是為什麼呢?
    * 原因:其實原因很簡單,因為我們雖然說是訪問的同一個對象,但是我們隨即就關閉了這個session而重新開啟了一個session,

        此時我們訪問時的session是不一致的也就是說是兩個不同的session發出的請求,這樣理解的話,我們就不難理解了。

          所以總結出,一級緩存是一個會話級別的緩存,當一次回話結束後該會話里的緩存則會全部的銷毀,所有我們自然就只能重新發送一條sql啦。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 查看現有tomcat的記憶體大小情況1、啟動tomcat 2、訪問 http://localhost:8080/manager/status ,並輸入您在安裝tomcat時輸入的用戶與口令,如 admin ,密碼 admin(密碼是您在tomcat安裝時輸入的) 註:添加用戶,修改conf/tomca ...
  • 面試的時候經常會問到Java的單例模式,這道題能很好的考察候選人對知識點的理解程度。單例模式要求在系統運行時,只存在唯一的一個實例對象。 下麵我們來詳細剖析一下其中的關鍵知識點,並介紹五種實現方法,以及它們的優缺點。 一、最簡單的方法是在類載入的時候初始化這個單獨的實例。 首先,定義單例類(沒有特別 ...
  • 一.什麼是集合 集合是對象的集合,就像數組是數的集合。集合是一種容器,可以存放對象(可以是不同類型的對象)。 二.集合的優點(為什麼要用集合) 當然,在java里,可以使用數組來存放一組類型相同的對象。但是數組存放對象有兩個缺點(集合優點): 三.集合的實現 java中集合主要由兩個介面實現:Col ...
  • 1.清屏 Ctrl + L 2.退出 q() 3.設置工作空間 getwd() setwd('D:\\Program Files\\RStudio\\workspace') 4.顯檔當前工作目錄下的文件列表 list.files() choose.dir() dir("D:\\Program Fil... ...
  • 簡單值 一半頂層settings元素是簡單值,它們表示的一系列值可以配置Maven的核心行為:settings.xml中的簡單頂層元素 < settings xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi= "http://www.w3.org ...
  • 前兩天偷懶,沒有堅持,今天開始,希望能堅持下去, 今天主要學習的是數據類型,關於python,數據類型主要有整型(int)、布爾類型(bool)、浮點型(float)、E記法(E) 舉例說明,整型(int)主要為整數,布爾類型(bool)為判斷,true或者false。浮點型(float)包含小數點 ...
  • 一、概述 模板方法模式在一個方法中定義一個演算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在不改變演算法結構的情況下,重新定義演算法中的某些步驟。 二、結構類圖 三、解決問題 模板方法就是提供一個演算法框架,框架裡面的步驟有些是父類已經定好的,有些需要子類自己實現。相當於要去辦一件事情,行動的流 ...
  • [轉載]協程三講 http://ravenw.com/blog/2011/08/24/coroutine-part-1-defination-and-classification-of-coroutine/ http://ravenw.com/blog/2011/09/01/coroutine-pa ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...