Hibernate入門(二)

来源:https://www.cnblogs.com/gdwkong/archive/2018/02/11/8324200.html
-Advertisement-
Play Games

本文主要介紹Hibernate主鍵的生成策略、持久化類的編寫規則、 持久化對象的三種狀態、hibernate的緩存、Hibernate的事務。 ...


一、主鍵生成策略

1.主鍵的類型

  • 自然主鍵: 把有特定業務含義的欄位作為了主鍵 eg: 用戶的名字, 身份證號碼

  • 代理主鍵: 把沒有特定業務含義的欄位作為了主鍵 eg: id

  開發裡面的話通常用代理主鍵

2.主鍵的生成策略

2.1概述

​ Hibernate中為了更好的維護數據, 提供很多種主鍵生成策略.

2.2 主鍵策略類型
  • increment :自動增長,適用類型:short,int,long類型主鍵.在多進程和集群下不要使用.用的不是資料庫的自動增長, hibernate底層的增長策略,select max(id) from customer; 然後+1作為下一條記錄的ID.

  • assigned:需要用戶手動輸入OID的.

  • identity:自動增長,用的是資料庫的自動增長。適用類型:short,int,long類型主鍵.支持自動增長資料庫如Mysql

  • sequence:序列,適用類型:short,int,long類型主鍵.支持序列的資料庫如:Oracle.

  • native:本地策略,根據資料庫的底層採用使用identity還是sequence.

  • uuid:隨機的字元串,適用於字元串類型的主鍵.

  規則: 如果主鍵類型是 int short long 用 native

​      如果主鍵類型是字元串, 用uuid

二、持久化類的編寫規則

1.持久化類概述

​   在Hibernate中,用來描述資料庫表結構的類,稱之為持久化類.

​   Java類與資料庫的某個表建立了映射關係.這個類就稱為是持久化類

​   持久化類 = Java類 + hbm的配置文件

2.持久化類定義規範

  • 遵循JavaBean定義規範

    ​ 類是公有的

    ​ 需要一個無參的構造函數

    ​ 屬性是私有的,需要提供公共的getter和setter方法進行訪問屬性

  • 必須用一個屬性描述資料庫表的主鍵

  • 主鍵屬性的類型必須是引用類型,且需要實現Serializable介面

三、 持久化對象的三種狀態

1.概述

​   由持久化類創建的對象就是持久化對象。Hibernate為了管理持久化對象:將持久化對象分成了三個狀態.hibernate底層實現過程中,定義的三種狀態主要方便開發人員調用session的API.

​   區分三種狀態:

​     瞬時態 :沒有持久化標識OID的,沒有納入到session的管理.

​     持久態 :有持久化標識OID的,已經納入到session的管理.

​     托管(游離態)態:有持久化標識OID的,沒有納入到session的管理.

java代碼:

/**
 * 區分三種狀態:
 * 瞬時態: 沒有持久化標識oid,沒有納入Session管理
 * 持久態: 有持久化標識oid,並且納入了Session管理
 * 托管態: 有持久化標識oid,但沒有納入Session管理
 */    
    @Test
    public void fun01(){
        Session session = HibernateUtils.openSession();
        Transaction transaction = session.beginTransaction();
        transaction.begin();
        
        User user = new User();//瞬時態
        user.setUname("張三");
        user.setUage(18);
        
        session.save(user);
        System.out.println(user.toString());//持久態
        
        transaction.commit();
        session.close();
        System.out.println(user.toString());//托管態
    }

2.三種狀態的轉換

2.1瞬時態對象

沒有持久化標識OID, 沒有被納入到Session對象的管理

  • 獲得:new對象

  • 狀態轉換:

    ​ 瞬時態--->持久態:save()/saveOrUpdate();

    ​ 瞬時態--->托管態:把瞬時態對象設置一個id

2.2持久態對象

有持久化標識OID,已經被納入到Session對象的管理

  • 獲得:get()/load()/find()..

  • 狀態轉換:

    ​ 持久態--->瞬時態:session.delete(); (Hibernate中不建議使用的)

    ​ 持久態--->托管態:close()/clear()/evict(Object obj);

2.3托管態對象

  有持久化標識OID,沒有被納入到Session對象的管理

  • 獲得:new對象,給對象設置id

  • 狀態轉換:

    ​ 托管態-->瞬時態:把對象的id設置為null

    ​ 托管態--->持久態:update()/saveOrUpdate();

3.持久態對象可以自動更新資料庫

  持久態對象依賴於緩存可以自動更新資料庫

  • Java代碼

 1     @Test
 2     public void fun05(){
 3         Session session = HibernateUtils.openSession();
 4         Transaction transaction = session.beginTransaction();
 5         transaction.begin();
 6         //持久態對象
 7         User user = session.get(User.class, 1);
 8         user.setUname("李四");
 9         //session.update(user);可以不寫,因為當前的user是持久化對象
10 
11         transaction.commit();
12         session.close();
13     }

四、hibernate的緩存

1.緩存概述

​   緩存就是一塊記憶體空間。

​   將數據源(資料庫或者文件)中的數據讀取出來存放到緩存中,再次獲取的時候 ,直接從緩存中獲取,這樣可以提升程式的性能!

​   作用:提升程式的性能

2.Hibernate的緩存類別

​   一級緩存:session對象的緩存,自帶的不可卸載的. 一級緩存的生命周期與session一致。

​   二級緩存:二級緩存可以在多個session中共用數據。一般不會用,企業里通常使用Redis

3.一級緩存

​   在 Session 介面的實現中包含一系列的 Java集合,這些 Java 集合構成了 Session 緩存. 只要 Session 實例沒有結束生命周期, 存放在它緩存中的對象也不會結束生命周期.

​   當session的save()方法持久化一個對象時,該對象被載入緩存,以後即使程式中不再引用該對象,只要緩存不清空,該對象仍然處於生命周期中。當試圖get()、 load()對象時,會判斷緩存中是否存在該對象,有則返回,此時不查詢資料庫。沒有再查詢資料庫.

    @org.junit.Test
    public void fun03(){
        Session session = HibernateUtils.openSession();
        Transaction transaction = session.beginTransaction();

        //持久態對象
        User user1 = session.get(User.class, 1);//馬上發送一條sql語句
        System.out.println(user1.toString());

        User user2 = session.get(User.class, 1);//馬上發送一條sql語句
        System.out.println(user1 == user2);//true

        transaction.commit();
        session.close();
    }

測試結果:

Hibernate:
  select
    user0_.uid as uid1_0_0_,
    user0_.uname as uname2_0_0_,
    user0_.uage as uage3_0_0_
  from
    user user0_
  where
    user0_.uid=?
User{uid=1, uname='李四', uage=18}
true

4.一級緩存的內部結構:(緩存區, 快照區)

五、Hibernate的事務

1.事務的概念

​   事務就是邏輯上的一組操作,組成事務的各個執行單元,操作要麼全都成功,要麼全都失敗.

2.事務的特性

​   原子性: 事務不可分割.

​     eg: 張三 1000 李四 1000; 張三給李四轉100, 要麼轉賬成功,要麼失敗

​   一致性: 事務執行的前後數據的完整性保持一致.

​     eg: 張三 1000 李四 1000 =2000; 張三給李四轉100, 成功了 張三 900 李四1100 = 2000; 失敗

  ​ 隔離性: 一個事務執行的過程中,不應該受到其他的事務的干擾.

​   持久性: 事務一旦提交,數據就永久保持到資料庫中.

​     eg: 張三 1000 李四 1000, 給李四轉520;

3.不考慮隔離性會出現的相關問題

  • 臟讀: 一個事務讀到了另一個事務未提交的數據.

  • 不可重覆讀: 一個事務讀到了另一個事務已經提交的update數據,導致多次查詢結果不一致. 張三 1000 ; 李四 1000

  • 虛讀: 一個事務讀到了另一個事務已經提交的insert數據,導致多次查詢結構不一致.

4.隔離級別

隔離級別含義
READ_UNCOMMITTED 允許你讀取還未提交的改變了的數據。可能導致臟、幻、不可重覆讀
READ_COMMITTED 允許在併發事務已經提交後讀取。可防止臟讀,但幻讀和 不可重覆讀仍可發生
REPEATABLE_READ 對相同欄位的多次讀取是一致的,除非數據被事務本身改變。可防止臟、不可重覆讀,但幻讀仍可能發生。
SERIALIZABLE 完全服從ACID的隔離級別,確保不發生臟、幻、不可重覆讀。這在所有的隔離級別中是最慢的,它是典型的通過完全鎖定在事務中涉及的數據表來完成的。

實際開發中,不會選擇最高或者最低隔離級別,選擇 READ_COMMITTED(oracle 預設)、REPEATABLE_READ (mysql預設)

5.Hibernate配置隔離級別

  hibernate通過在hibernate.cfg.xml的配置文件中設置隔離級別:

<property name="hibernate.connection.isolation">4</property>

  取值

    ​ 1: Read uncommitted isolation,讀未提交

​     2: Read committed isolation,讀已提交,解決臟讀。

​     4: Repeatable read isolation,可重覆讀

​     8: Serializable isolation,串列化

6.hibernate對 session的管理

6.1把Session綁定在當前線程

​   在開發中,通常在業務層進行事物管理,在Dao層操作資料庫. 也就是說業務層需要連接(Session)開啟事物,Dao層需要連接(Session)操作資料庫,如何保證這些連接是同一個呢?

​ 在JDBC階段,我們通過了兩種方式解決:

  ​ 1.向下傳遞參數

​   2.綁定到TreadLocal裡面.

​   在Hibernate中,Session 對象與本地線程綁定很簡單,只需要兩步:

  • 在hibernate.cfg.xml文件中,添加屬性,開啟與本地線程綁定的session

    <property name="hibernate.current_session_context_class">thread</property>
  • 通過SessionFactory的getCurrentSession()方法獲得Session

    Session session = sessionFactory.getCurrentSession();

    註意:通過getCurrentSession()方法獲得的session,無需調用close方法釋放資源。當事物提交或者回滾,會自動釋放資源.

6.2 Session獲取方式的區別
  • 調用getCurrentSession()方法時,會判斷當前線程中是否綁定了session。

    ​ 如果綁定了,直接返回線程中綁定的session

    ​ 如果沒有綁定,先去創建一個session,然後講session存儲到當前線程中,再返回。

  • 調用openSession()方法時,只會創建一個新的session,且不會存儲到當前線程。

  • 通過getCurrentSession()方法獲得的session,無需調用close方法釋放資源. 通過openSession()方法獲得的session需要手動釋放資源。


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

-Advertisement-
Play Games
更多相關文章
  • 由於本篇博文的項目都很簡單,所以本次開個特例,本次解析兩個項目,但是都很簡單的 項目一:用socket實現文件傳輸 本項目很簡單,作為小項目的預熱的,前面剛學完socket,這裡馬上又利用socket進行項目開發,難不倒各位 項目要求: 1.用socket完成文件上傳功能 2.文件位置可以設置 3. ...
  • 本文主要介紹Hibernate如何實現一對多、多對多表,實現相關操作。 ...
  • 這是畢業校招二面時遇到的手寫編程題,當時剛剛開始學習python,整個棧寫下來也是費了不少時間。畢竟語言只是工具,只要想清楚實現,使用任何語言都能快速的寫出來。 何為最小棧?棧最基礎的操作是壓棧(push)和退棧(pop),現在需要增加一個返回棧內最小值的函數(get_min),要求get_min函 ...
  • 記憶體限制:256 MiB時間限制:1000 ms標準輸入輸出 題目類型:傳統評測方式:文本比較 上傳者: 匿名 記憶體限制:256 MiB時間限制:1000 ms標準輸入輸出 題目類型:傳統評測方式:文本比較 上傳者: 匿名 提交提交記錄統計討論測試數據 題目描述 這是一道模板題。 輸入兩個多項式,輸 ...
  • Description 在組合博弈論中,Nim游戲是一個非常經典的問題,Nim游戲可描述如下:有n堆石子,每堆石子數分別為a1, a2, …, an (ai≥0)。現有兩人輪流從這n堆中取石子,每次必須從某一堆中取任意多的石子,至少要取一個,必須從同一堆中取石子,並且不能超過這一堆石子的總數。如果某 ...
  • 聯編的概念 聯編是指一個電腦程式自身彼此關聯的過程,在這個聯編過程中,需要確定程式中的操作調用(函數調用)與執行該操作(函數)的代碼段之間的映射關係。 意思就是這個函數的實現有多種,聯編就是把調用和對應的實現進行映射的操作。按照聯編進行的階段不同,可分為靜態聯編和動態聯編。 靜態聯編 靜態聯編工作 ...
  • 前言 當前大多數app都有查找附近的功能, 簡單的有查找周圍的運動場館, 複雜的有滴滴, 摩拜查找周圍的車輛. 本文主要闡述查找附近地點的一般實現. 搜索附近的人也是同樣的思路. 方案比較 方案1 (性能還不錯) 資料庫直接存經緯度, 然後計算矩形邊界值, 走索引查詢 方案2 (還沒試過) 將經緯度 ...
  • python字元串格式化兩種方式:百分號方式、format方式 用百分號字元串拼接 列印浮點數: 列印百分比: format ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...