1. 程式人生 > >理解Hibernate的Session和快取機制

理解Hibernate的Session和快取機制

理解Session
Session的主要功能是提供對映的實體類例項的建立,讀取和刪除操作,這裡與Http協議不同
Session可能存在以下三種狀態:
臨時狀態(transient):不曾進行持久化,未與任何Session相關聯
持久化狀態(persistent):僅與一個Sessionxiangguanlian
遊離狀態(detached):已經進行過持久化,但當前未與任何Session相關聯

session具體實現斌不一定是執行緒安全的,因此最好是一個執行緒就用一個Session物件,每個執行緒/事務應該從一個SessionFactory獲取自己的session例項
這種不是針對資料庫操作,而是針對session(或者其他框架針對model物件,或者pojo物件)的操作可以理解成是進一步的抽象,可以讓開發者乾脆從程式碼角度不知道資料庫的做法,可更讓資料庫優化和業務邏輯的有效剝離,這樣讓兩者更專業不會相互干擾。

HQL
HQL(Hibernate Query Language)
1 這個是main相對相的查詢語言
2 HQL中查的是物件而不是表
3 HQL主要通過Query來操作,Query的建立方式:
Query q = session.createQuery(hql);
from 類名
from 類名 where user.name = :name
HQL和SQL查詢語言有些相似,它支援如下各種查
詢功能:

1 設定各種查詢條件

2 能檢索出物件的部分屬性

3 支援分頁查詢

4 支援連線查詢

5 支援分組查詢,可以使用having和group by關鍵字
,也能使用內建聚集函式,如:sum等

6 支援子查詢,即諸如Exist, in等查詢

7 使用者可以動態地傳入引數
在Hibernate中,例項化的Session是一個輕量級的類,建立和銷燬它都不會佔用很多資源,這在實際專案中意義很大,因為在客戶端程式中可能會不斷的建立以及銷燬Session物件。
Session介面中針對單條記錄的基本curd操作方法
save()方法:把Java物件儲存資料庫中

update()方法:更新資料庫中的Java物件

delete()方法:把Java物件從資料庫中刪除

load()方法:從資料庫中載入Java物件

find()方法:從資料庫中查詢Java物件

Transaction(事物)介面

1 事務將應用程式碼從下層的事物實現中抽象出來
2 這樣將允許應用通過一組一致的API控制事務

SessionFactory介面
1利用工廠類SessionFactory中取得Session的例項
2SessionFactory並不是輕量級的
3每個資料儲存源對應建立一個SessionFactory

Hibernate的快取
Hibernate的快取分為:
1一級快取,單個會話的快取

2二級快取,可插拔的快取外掛,一般是由第三方控制元件提供 。
1當Session載入或儲存一個物件時,該物件將被Session快取
2當再次通過Session載入相同ID的物件時,Hibernate將直接從Session的快取中獲取
3當Session關閉時,快取將被清空
//第一次載入時將產生SQL訪問資料庫,1L是主鍵的值

User user = (User)session.get(User.class, 1L);

//第二次載入同樣的Customer時Hibernate將從Session中獲取

User user1 = (User)session.get(User.class, 1L);

//cusa和cusb應當是同一物件
If(user == user1) System.out.println(“是同一個物件!”);

//快取被清空

session.close();
快取的優勢:
1可以減少訪問資料庫的次數
因公存續從記憶體中獲取的物件明顯快於從資料庫中查詢
2保證快取中的物件與資料庫相關的記錄同步
當快取中的物件屬性改變時,session不會立即更新資料庫(這樣會頻繁訪問資料庫影響效能),而是將多次更新合併處理後產生一條更新語句。

User user = (User)session.load(User.class, 1L);

user.setName("jack");
user.setName("mike");

//在Hibernate的最終實現裡,以上只會產生一條sql語句;

update Customer set name = ‘mike’ …

Hibernete會在特定的時間自動同步快取資料庫
1手動提交事務時
2執行session的查詢方法時
3執行session.flush時
但是關閉session時,Hibernate不會執行快取同步

Hibernate快取是一個可以插拔的快取外掛,他又SessionFactory負責管理,由於SessionFactory物件的生命週期和應用程式的生命週期對應,因此二級快取的是程序範圍或群及範圍
二級快取是可選的,可以在每個類或每個集合的粒度上配置二級快取
這裡寫圖片描述

1 Hibernate預設使用EhCacheProvider提供二快取支援,而且可以通過配置引數hibernate.cache.provider_class設定相關的快取器。

2 可以通過在元素或等集合元素中配置來設定Hibernate的二級快取策略

3 或者可以通過Hibernate的配置引數或指定二級快取的策略。

配置屬性:
1 usage元素用於制定快取的策略
read-only:快取的物件只可讀取
read-write:快取的物件可讀寫
nonstrict-read=write:非常嚴格的讀寫,適用於併發更新的情況非常小
transaction:適用於jta事物範圍內的快取
2 region元素用於指定快取物件存放的區域名,如果不設定,預設的值是類名或集合名
3include元素表示快取物件的種類
二級快取使用示例
//Customer使用讀寫二級快取

省略其他語句


User user = (User)session.get(User.class, 1L);

//關閉Session,一級快取將清空,但二級快取中仍保留有user的資料
session.close();

//開啟session再次獲取User時,並未產生一條SQL

//Hibernate此時是從二級快取中,而不是資料庫中獲取該資料。

User user = (User)session.get(User.class, 1L);