Hibernate運用/詳解

一、   Hibernate實現Web開發的基本步驟-簡

(1)   創建數據庫

(2)   將Hibernate所需要的JAR包導入項目(WEB-INF/lib下)

(3)   創建Hibernate的配置文件

(4)   利用Hibernate的第三方工具或者eclipse的有關插件從數據庫中創建出相應的實體對象、ORM映射文件(Hibernate支持註解之後無此配置文件)

(5)   創建Hibernate的SessionFactory類

(6)   通過SessionFactory創建Session實例

(7)   通過創建的Session實例踐行持久化對象的管理(CRUD)

(8)   通過創建的Transaction實例進行事務管理

(9)   通過創建的Query或者Criteria實例實現數據庫的查詢

二、   Hibernate的核心接口和類

Hibernate的核心類和接口一共有6個,分別爲:Session、SessionFactory、Transaction、Query、Criteria和Configuration。這6個核心類和接口在任何開發中都會用到。通過這些接口,不僅可以對持久化對象進行存取,還能夠進行事務控制,這一節先對這6個核心接口簡要說一下,再接下來的幾節會做詳細介紹。

1.     Configuration

Configuration 類的作用是對Hibernate 進行配置,以及對它進行啓動。在Hibernate 的啓動過程中,Configuration 類的實例首先定位映射文件的位置,讀取這些配置,然後創建一個SessionFactory對象。雖然Configuration 類在整個Hibernate 項目中只扮演着一個很小的角色,但它是啓動hibernate 時所遇到的第一個對象。

2.     SessionFactory

SessionFactory接口負責初始化Hibernate。它充當數據存儲源的代理,並負責創建Session對象。這裏用到了工廠模式。需要注意的是SessionFactory並不是輕量級的,因爲一般情況下,一個項目通常只需要一個SessionFactory就夠,當需要操作多個數據庫時,可以爲每個數據庫指定一個SessionFactory。

3.     Session

Session接口負責執行被持久化對象的CRUD操作(CRUD的任務是完成與數據庫的交流,包含了很多常見的SQL語句)。但需要注意的是Session對象是非線程安全的。同時,Hibernate的session不同於JSP應用中的HttpSession。這裏當使用session這個術語時,其實指的是Hibernate中的session,而以後會將HttpSession對象稱爲用戶session。

4.     Transaction

Transaction 接口是一個可選的API,可以選擇不使用這個接口,取而代之的是Hibernate 的設計者自己寫的底層事務處理代碼。 Transaction 接口是對實際事務實現的一個抽象,這些實現包括JDBC的事務、JTA 中的UserTransaction、甚至可以是CORBA 事務。之所以這樣設計是能讓開發者能夠使用一個統一事務的操作界面,使得自己的項目可以在不同的環境和容器之間方便地移植。

5.     Query

Query接口讓你方便地對數據庫及持久對象進行查詢,它可以有兩種表達方式:HQL語言或本地數據庫的SQL語句。Query經常被用來綁定查詢參數、限制查詢記錄數量,並最終執行查詢操作。

6.     Criteria

Criteria接口與Query接口非常類似,允許創建並執行面向對象的標準化查詢。值得注意的是Criteria接口也是輕量級的,它不能在Session之外使用。

三、   Hibernate的體系結構

在Hibernate的體系結構中,Hibernate Session這個概念非常重要,只有處於Session管理下的POJO纔有持久化操作的能力。當應用程序對處於Session管理下的POJO實例執行操作時,Hibernate將這種面向對象的操作轉換爲持久化操作。在使用Hibernate時,需要用到一個名爲hibernate。properties的文件,此文件用於配置Hibernate與數據庫的連接信息。還有映射文件(現在基本使用註解形式,持久化類和數據表之間的映射文件就不需要了)。

Hibernate的持久化解決方案將用戶從原始的JDBC訪問中釋放出來,用戶無需關心底層的JDBC操作,而是以面型對象的方式進行持久化操作。底層數據連接的獲得、數據訪問的實現、事務控制都無需用戶關心。這是一種“全面解決”的體系結構方案,將應用層從底層的JDBC/JTA API中抽象出來。

一個簡要的 Hibernate 整體體系結構大致如下圖所示:

Application:應用

persistent objects:持續化對象

properties:屬性,性能

XML Mapping:XML映射

從上圖可以看出,Hibernate 使用數據庫(Database)和配置信息(hibernate.properties 等)來爲應用程序提供持久化服務(以及持久的對象 Persistent Objects)。

我們再來看看 Hibernate 運行時的體系結構。由於Hibernate非常靈活,且支持多種應用方案,所以這裏我們只描述一下兩種極端的情況。

1、 “輕型”的體系結構方案

要求應用程序提供自己的 JDBC 連接並管理自己的事務。這種方案使用了 Hibernate API 的最小子集:

2、 “全面解決”的體系結構方案

將應用層從底層的 JDBC/JTA API 中抽象出來,而讓 Hibernate 來處理這些細節:

四、   使用Hibernate操作數據(最基本)

        從上往下依次進行:

(1)   創建一個Configuration實例conf並且調用.configure()方法加載配置文件

(2)   conf.buildSessionFactory()創建一個SessionFactory類sf

(3)   sf.openSession()創建一個Session類sess

(4)   sess.beginTransaction()創建一個Transaction事務類tx,開啓事務

(5)   操作實體

(6)   sess.save(entity);保存消息

(7)   tx.commit()提交事務

(8)   sess.close();關閉Session

(9)   sf.close();關閉SessionFactory

        也就是說,Hibernate的工作流程是:首先通過configuration對象讀取配置文件;解析映射信息,創建StandardSessionFactory;調用openSession打開session;創建事務transaction,之後進行持久化操作;完成後提交事務,關閉session,關閉sessionFactory。

五、   核心接口之Configuration

1)    接口介紹

        Configuration接口的作用是Hibernate進行配置,以及對他進行啓動,在Hibernate的啓動過程中,Configuration類的實例首先定位映射文檔的位置,讀取這些配置,然後創建一個SessionFactory對象

        一個org.hibernate.cfg.Configuration實例代表了一個應用程序中Java類型到SQL數據庫映射的完整集合。Configuration被用來構建一個不可變的SessionFactory,映射定義則由不同的XML映射定義文件編譯而來。

2)    Configuration有以下幾個方面的操作函數

(1)爲Configuration指定映射文件

        你可以直接實例化Configuration來獲取一個實例併爲他指定XML映射定義文件 如果映射定義文件在類路徑中 請使用addResource()

Configuration cfg = new Configuration().addResource("com/demo/hibernate/beans/User.hbm.xml");

(2)爲Configuration指定持久化類

        一個替代的方法是指定被映射的類 讓Hibernate幫你尋找映射定義文件

Configuration cfg = new Configuration().addClass(com.demo.hibernate.beans.User.class);

        Hibernate將會在類路徑中需找名字爲/com/demo/hibernate/beans/User.hbm.xml 映射定義文件 消除了任何對文件名的硬編譯

      (3)爲Configuration指定配置屬性

      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");

六、   核心接口之SessionFactory

        接口SessionFactory使用工廠設計模式。通過SessionFactory對象可以獲取Session對象,Hibernate4已經將configuration的buildSessionFactory方法已經劃線了,說明已經過時了,不過這不影響我們web開發人員使用(如果不追求極致深層次的話)。

        參看hibernate源碼。以及API幫助文檔,發現Hibernate4新增了一個接口ServiceRegistry,所有基於Hibernate的配置或者服務都必須統一向這個ServiceRegistry註冊後才能生效。所以不難看出 Hibernate4的配置入口不再是Configuration對象,而是ServiceRegistry對象,Configuration對象將通過ServiceRegistry對象獲取配置信息。使用了Builder模式創建一個ServiceRegistry對象,可以看到源碼org.hibernate.service.ServiceRegistryBuilder這個類。

具體獲取如下:

import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;

public class Test {

    private static Configuration configuration = null;
    private static SessionFactory sessionFactory = null;
    private static ServiceRegistry serviceRegistry = null;
    public static void main(String[] args) {
        try {
            configuration = new Configuration().configure();
            serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
            sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        } catch (HibernateException e) {
            e.printStackTrace();
        }
    }

}

七、   核心接口之Session

1)    Session介紹

        Session:是應用程序與數據庫之間的一個會話,是hibernate運作的中心,持久層操作的基礎。持久化對象的生命週期、事務的管理、數據庫的查詢、存取都與Session息息相關。Hibernate在操作數據庫之前必須先取得Session對象,相當於JDBC在操作數據庫之前必須先取得Connection對象一樣。

Session對象不是線程安全的(ThreadSafe),一個Session對象最好只由一個單一線程來使用。

2)    Session創建

        Session對象是通過SessionFactory構建的,有兩種方式分別是:getCurrentSession()或者openSession(),在Spring的管理中我們可以這樣獲取Session:

@Autowired
	private SessionFactory sessionFactory;  
    public Session getSession() {  
        return sessionFactory.getCurrentSession();  
    }
    @Override
	public T save(T entity){
		Session session = getSession();
		session.save(entity);
		return entity;
	}

3)    需要注意點

(1)openSession和getCurrentSession的區別?

*openSession必須關閉,currentSession在事務結束後自動關閉

*openSession沒有和當前線程綁定,currentSession和當前線程綁定

如果使用currentSession需要在hibernate.cfg.xml文件中進行配置:

*如果是本地事務(jdbc事務)

<propertyname="hibernate.current_session_context_class">thread</property>

*如果是全局事務(jta事務)

<propertyname="hibernate.current_session_context_class">jta</property>

全局事務:資源管理器管理和協調的事務,可以跨越多個數據庫和進程。資源管理器一般使用XA 二階段提交協議與“企業信息系統”(EIS) 或數據庫進行交互。 

本地事務:在單個 EIS或數據庫的本地並且限制在單個進程內的事務。本地事務不涉及多個數據來源。

(2)和jdbc的聯繫

       獲取Session對象後,Hibernate內部並不會獲取操作數據庫的java.sql.Connection對象,而是等到Session對象真正需要對數據庫進行CRUD等操作時,纔會從數據庫連接池中獲取java.sql.Connection對象。

       而關閉Session對象時,則是將java.sql.Connection對象返回連接池,而不是直接關閉java.sql.Connection對象。

八、   核心接口之Transaction

摘自-《開源中國》黃勇的文章《Transaction 那點事兒》,

九、   核心接口之Query

	Session session = getSession();
		String hql = null;
		hql = "from Authorization where serviceId ='"+serviceId+"'";
		Query query = session.createQuery(hql);
		Authorization authorization = (Authorization) query.uniqueResult();
		return null;

        上面代碼只是爲了說明Query這個接口的用法,具體的詳細內容還要在實踐中去獲得,這裏就不詳細介紹了。

十、   核心接口之Criteria

        Hibernate進行軟件開發進行數據查詢時,主要基於HQL(Hibernate 面向對象的查詢語言,語法類似SQL)、Criteria(面向對象的條件查詢對象)、SQL(原生態SQL語句)幾種方式。

        Criteria 是一個完全面向對象,可擴展的條件查詢API,通過它完全不需要考慮數據庫底層如何實現、SQL語句如何編寫,是Hibernate框架的核心查詢對象。Hibernate 定義了CriteriaSpecification接口規範用來完成面向對象的條件查詢,Criteria就是CriteriaSpecification的子接口

        Criteria與Session綁定,其生命週期跟隨着Session結束而結束,使用Criteria時進行查詢時,每次都要於執行時期動態建立物件,並加入各種查詢條件,隨着Session的回收,Criteria也跟着回收。

Session session = getSession();
Criteria criteria = session.createCriteria(clazz);

        CriteriaDetachedCriteriaCriteria DetachedCriteria 的主要區別在於創建的形式不一樣, Criteria 是在線的,是由Hibernate Session 進行創建的;而 DetachedCriteria 是離線的,創建時無需Session)均可使用CriterionProjection 設置查詢條件。可以設置 FetchMode( 聯合查詢抓取的模式 ) ,設置排序方式。對於 Criteria 還可以設置 FlushModel(沖刷 Session 的方式)和 LockMode (數據庫鎖模式)。

        Criterion 是 Criteria 的查詢條件。Criteria提供了 add(Criterion criterion) 方法來添加查詢條件。

        Criterion 的實例可以通過 Restrictions 工具類來創建,Restrictions 提供了大量的靜態方法,如 eq (等於)、 ge (大於等於)、 between 等來方法的創建 Criterion 查詢條件(SimpleExpression 實例)

Criterion criterion1 = Restrictions.like(“name”,”李%”);
Criterion criterion2 = Restrictions.like(“id”,new Integer(1),new Integer(10));

criteria.add(criterion1);
criteria.add(criterion2);

十一、   Hibernate中對象的三種狀態

1.     瞬時態

        hibernate中什麼時候的對象爲瞬時態呢,當我們new 一個對象時,還沒有save時,它就是瞬時態的,當我們delete一個對象時,它也是瞬時態了,因爲此時,他們在數據庫中沒有對應的記錄存在。兩點特徵:

        1)不在Session的緩存中,不與任何的Session實例相關聯

        2)在數據庫中沒有與之相對應的記錄

2.      持久態

        當我們save一個對象時,這個對象會保存到數據庫,同時也會緩存在session中,同時,當我們get(),load(),updateOrSave()一個對象時,也會將這個對象緩存在session中,這時緩存中的對象與數據庫是同步的,也就是持久態的,任何一方的改變都會同步更新。兩點特徵:

        1)在Session的緩存中,與Session實例相關聯。

        2)在數據庫中存在與之相對應的記錄

3.     遊離態

        當對象從持久態轉變爲另一狀態時,這個狀態就是遊離態了。比如:session.close(),session.evict()對象時,對象從session緩存中清除,數據庫中有數據,緩存中沒有數據,因爲數據庫中有數據,所以它是可以再被持久化的.兩點特徵:

        1)不在Session的緩存中,不與任何Session實例相關聯。

        2)在數據庫中存在與之相對應的記錄(前提是沒有其他Session實例刪除該條記錄)。







發佈了24 篇原創文章 · 獲贊 9 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章