Hibernate(三):Hibernate核心類,介面
一,Configuration
Configuration是 一個介面,作用是對它進行啟動,以及負責管理Configuration的配置資訊,包括以下內容:
- Hibernate執行的底層資訊:資料庫的URL,使用者名稱,密碼,JDBC驅動,資料庫的Dialect,資料庫連線池(對應hibernate.cfg,xml)
- 持久化類與資料表的對映關係(*.hbm.xml)
在Hibernate啟動的過程中Configuration的例項首先先定義對映文件的文職,讀取這些配置,然後建立一個SessionFactory物件。
一個org.hibernate.cfg.Configuration例項代表了一個應用程式中Java型別到SQL資料庫對映的完整集合。Configuration被用來構建一個不可變的SessionFactory,對映定義則由不同的XML對映定義檔案編譯而來。
1.為Configuration指定對映檔案
可以直接例項化Configuration來獲取一個例項,併為它指定XML對映檔案,如果對映檔案在類路徑中,請使用addResource()
Configuration cfg = new Configuration().addResource("類路徑");
2.為Configuration指定持久化類
指定被對映的類, 讓Hibernate去尋找對映定義檔案
Configuration cfg=new Configuration().addClass(com.hibernate.beans.User.class);
Hibernate會在類路徑中尋找名字為/com/ibernate/beans/User.hbml.xml對映定義檔案
3,為Configuration指定配置屬性
4.Configuration的載入方式Configuration cfg =new Configuration().addClass(com.demo.hibernate.beans.User.class) .setProperty("hibernate.dialect","org.hibernate.dialect.MySQLInnoDBDialect") .setProperty("hibernate.connection.datasource","java:comp/env/jdbc/test") .setProperty("hibernate.order_update","true");
在Hibernate的啟動與開發中,需要使用一個Configuration,需要為它設定三個內容:資料庫連線屬性,hbm,xml,POJO類(第二個和第三個只需設定一個,就會自動尋找另一個)
(1)使用hibernate.cfg.xml。該檔案設定了資料庫連線屬性和hbm.xml對映檔案配置。Hibernate會自動載入該配置屬性。
Configuration cfg = new Configuration();
cfg.configuration("hibernate.cfg.xml");
(2)使用hibernate.properties
Configuration cfg = new Configuration();
(3)在完全構造時進行硬編碼構造:
Configuration cfg =new Configuration()
.addClass(com.demo.hibernate.beans.User.class)
.setProperty("hibernate.dialect","org.hibernate.dialect.MySQLInnoDBDialect")
.setProperty("hibernate.connection.datasource","java:comp/env/jdbc/test")
.setProperty("hibernate.order_update","true");
二,SessionFactory
SessionFactory介面負責初始化Hibernate,充當資料儲存源的代理。起到一個緩衝區的作用,緩衝了Hibernate自動生成的 SQL語句和其他對映資料,緩衝了一些將來有可能重複利用的資料。
1.特點:
針對單個數據庫對映關係經過編譯後的記憶體映象,是執行緒安全的
SessionFactory物件一旦構造完成,即被賦予特定的配置資訊(一旦SessionFactory構造完成,配置檔案變更不再影響物件)
構造SessionFactory很浪費資源,一般情況下只初始化一個SessionFactory物件。
如果操作多個數據庫,必須為每個資料庫指定一個SessionFactory
2.建立SessionFactory物件:
(1)例項化Configuration物件,預設讀取src目錄下的hibernate.cfg.xml配置檔案
Configuration cfg = new Configuration();
cfg.configuration("hibernate.cfg.xml");
(2)通過Configuration的buildSessionFactory()方法構建唯一的SessionFactorySessionFactory sessionFactory = config.buildSessionFactory
Hibernate4 新增了一個 ServiceRegistry 介面,所有基於 Hibernate 的配置或者服務都必須統一向這個 ServiceRegistry 註冊後才能生效
Hibernate4 中建立 SessionFactory 的步驟
三,Session
Session介面是Hibernate嚮應用程式提供操作資料庫的主要介面,它是抽象了持久化服務概念的核心抽象API類,提供了基本的儲存,更新,刪除和載入Java物件的方法。
特點:
(1) 是應用程式與資料庫之間互動操作的一個單執行緒物件,是Hibernate的運作中心
(2)所有持久化物件必須在Session的管理下才可以進行持久化操作
(3)單執行緒,生命週期短,代表了一次會話過程
(4)每一個Session例項與一個數據庫事務繫結:每執行一個數據庫事務操作,就先建立一個Session例項,如果事務執行出現異常,撤銷事務。無論成功與否,都要呼叫Session的close()方法,釋放例項佔用的資源
(5)物件的例項狀態就是之前提到過的三種:臨時狀態(自由),持久化狀態,遊離狀態。
(6)Session提供的方法使物件的狀態在這三種狀態中來回的變換:
- 自由狀態的例項可以通過呼叫 save(),persist()或者saveOrUpdate() 方法進行持久化。
- 持久化例項可以通過呼叫delete()變成遊離狀態。
- 通過get()或load()方法得到的例項都是持久化狀態的。
- 遊離狀態的例項可以通過呼叫 update(),saveUpdate(),lock()或者replicate() 進行持久化。
- 遊離或者自由狀態下的例項可以通過呼叫merge()方法成為一個新的持久化例項。
Session介面中的方法如下:
Method Summary | |
void |
clear() 完整的清除這個session。 |
close() 停止這個Session,通過中斷JDBC連線並且清空(cleaning up)它。 |
|
獲取這個Session的JDBC連線。 如果這個session使用了積極的collection釋放策略(如CMT-容器控制事務的環境下),關閉這個呼叫的連線的職責應該由當前應用程式負責。 |
|
boolean |
檢查這個物件例項是否與當前的Session關聯(即是否為Persistent狀態)。 |
(Class persistentClass) 為給定的實體類或它的超類建立一個新的Criteria例項。 |
|
根據給定的實體類或者它的超類建立一個新的Criteria例項,並賦予它(實體類)一個別名。 |
|
根據給定的實體的名稱(name),建立一個新的Criteria例項。 |
|
根據給定的實體的名稱(name),建立一個新的Criteria例項,並賦予它(實體類)一個別名 |
|
Query |
根據給定的collection和過濾字串(查詢條件)建立一個新的Query例項。 |
Query |
根據給定的HQL查詢條件建立一個新的Query例項。 |
根據給定的SQL查詢條件建立一個新的SQLQuery例項。 |
|
void |
從資料庫中移除持久化(persistent)物件的例項。 |
void |
從資料庫中移除持久化(persistent)物件的例項。 |
void |
禁用當前session的名稱過濾器。 |
void |
evict(Object object) 將當前物件例項從session快取中清除。 |
void |
flush() 強制提交重新整理(flush)Session。 |
get(Class clazz,Serializable id) 根據給定標識和實體類返回持久化物件的例項,如果沒有符合條件的持久化物件例項則返回null。 |
|
根據給定標識和實體類返回持久化物件的例項,如果沒有符合條件的持久化物件例項則返回null。 |
|
返回與給定的實體命名和標識匹配的持久化例項,如果沒有對應的持久化例項則返回null。 |
|
返回與給定的實體類和標識所匹配的持久化例項,如果沒有對應的持久化例項則返回null。 |
|
獲取給定的實體物件例項在Session的快取中的標識,如果該例項是自由狀態(Transient)的或者與其它Session關聯則丟擲一個異常。 |
|
Query |
從對映檔案中根據給定的查詢的名稱字串獲取一個Query(查詢)例項。 |
根據給定的實體模式(Entity Mode)開始一個新的有效的Session。 |
|
獲取與這個session關聯的Transaction(事務)例項。 instance associated with this session. |
|
boolean |
檢查當前Session是否處於連線狀態。 |
boolean |
當前Session是否包含需要與資料庫同步的(資料狀態)變化 ?如果我們重新整理提交(flush)這個session是否會有SQL執行? |
boolean |
檢查當前Session是否仍然開啟。 |
load(Class theClass,Serializable id) 在符合條件的例項存在的情況下,根據給定的實體類和標識返回持久化狀態的例項。 |
|
load(Class theClass,Serializable id,LockMode lockMode) 在符合條件的例項存在的情況下,根據給定的實體類、標識及指定的鎖定等級返回持久化狀態的例項。 |
|
void |
將與給定的標示對應的持久化狀態(值)複製到給定的自由狀態(trasient)例項上。 |
在符合條件的例項存在的情況下,根據給定的實體類和標識返回持久化狀態的例項。 |
|
在符合條件的例項存在的情況下,根據給定的實體類、標識及指定的鎖定等級返回持久化狀態的例項。 |
|
void |
lock(Object object,LockMode lockMode) 從給定的物件上獲取指定的鎖定級別。 |
void |
lock(String entityName,Object object,LockMode lockMode) 從給定的物件上獲取指定的鎖定級別。 |
merge(Object object) 將給定的物件的狀態複製到具有相同標識的持久化物件上。 |
|
merge(String entityName,Object object) 將給定的物件的狀態複製到具有相同標識的持久化物件上。 |
|
void |
將一個自由狀態(transient)的例項持久化。 |
void |
將一個自由狀態(transient)的例項持久化。 |
void |
|
void |
從資料庫中重新讀取給定例項的狀態。 |
void |
根據指定的鎖定模式(LockMode),從資料庫中重新讀取給定例項的狀態。 |
void |
使用當前的標識值持久化給定的遊離狀態(Transient)的實體。 |
void |
使用當前的標識值持久化給定的遊離狀態(Transient)的實體。 |
save(Object object) 首先為給定的自由狀態(Transient)的物件(根據配置)生成一個標識並賦值,然後將其持久化。 |
|
save(String entityName,Object object) 首先為給定的自由狀態(Transient)的物件(根據配置)生成一個標識並賦值,然後將其持久化。 |
|
void |
根據給定的例項的標識屬性的值(注:可以指定unsaved-value。一般預設null。)來決定執行 save() 或update()操作。 |
void |
根據給定的例項的標識屬性的值(注:可以指定unsaved-value。一般預設null。)來決定執行 save() 或update()操作。 |
void |
將一個未經更改的持久化物件設定為只讀模式,或者將一個只讀物件標記為可以修改的模式。 |
void |
根據給定的detached(遊離狀態)物件例項的標識更新對應的持久化例項。 |
void |
根據給定的detached(遊離狀態)物件例項的標識更新對應的持久化例項。 |
(7)獲得Session物件:
- 獲得SessionFactory物件(上面已講過用法)
- 根據SessionFactory例項物件獲取Session
Configuration config = new Configuration().configure();
SessionFactory sessionFactory = config.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
....
tx.commit();
session.close();
(8)管理Session
Hibernate 自身提供了三種管理 Session 物件的方法
- Session 物件的生命週期與本地執行緒繫結
- Session 物件的生命週期與 JTA 事務繫結
- Hibernate 委託程式管理 Session 物件的生命週期
- thread: Session 物件的生命週期與本地執行緒繫結
- jta*: Session 物件的生命週期與 JTA 事務繫結
- managed: Hibernate 委託程式來管理 Session 物件的生命週期
- 當一個執行緒(threadA)第一次呼叫 SessionFactory 物件的 getCurrentSession() 方法時, 該方法會建立一個新的 Session(sessionA) 物件, 把該物件與 threadA 繫結, 並將 sessionA 返回
- 當 threadA 再次呼叫 SessionFactory 物件的 getCurrentSession() 方法時, 該方法將返回 sessionA 物件
- 當 threadA 提交 sessionA 物件關聯的事務時, Hibernate 會自動flush sessionA 物件的快取, 然後提交事務, 關閉 sessionA 物件. 當 threadA 撤銷 sessionA 物件關聯的事務時, 也會自動關閉 sessionA 物件
- 若 threadA 再次呼叫 SessionFactory 物件的 getCurrentSession() 方法時, 該方法會又建立一個新的 Session(sessionB) 物件, 把該物件與 threadA 繫結, 並將 sessionB 返回
News news=null;
for(int i=0;i<10000;i++){
news=new News();
news.setTitle("--"+i);
session.save(news);
if((i+1)%20==0){
session.flush();
session.clear();
}
}
批量更新: 在進行批量更新時, 如果一下子把所有物件都載入到 Session 快取, 然後再快取中一一更新, 顯然是不可取的- 使用可滾動的結果集 org.hibernate.ScrollableResults, 該物件中實際上並不包含任何物件, 只包含用於線上定位記錄的遊標. 只有當程式遍歷訪問 ScrollableResults 物件的特定元素時, 它才會到資料庫中載入相應的物件.
- org.hibernate.ScrollableResults 物件由 Query 的 scroll 方法返回
通過 Session 來進行處理操作會受到以下約束
- 需要在 Hibernate 配置檔案中設定 JDBC 單次批量處理的數目, 應保證每次向資料庫傳送的批量的 SQL 語句數目與 batch_size 屬性一致
- 若物件採用 “identity” 識別符號生成器, 則 Hibernate 無法在 JDBC 層進行批量插入操作
- 進行批量操作時, 建議關閉 Hibernate 的二級快取