Hibernate3.x過(guò)濾器的高級(jí)應(yīng)用

字號(hào):

在很多應(yīng)用程序中不需要一次使用數(shù)據(jù)表中的所有的數(shù)據(jù)。在這種情況下,我們就需要使用Hibernate的過(guò)濾器(Filter)來(lái)得到一個(gè)數(shù)據(jù)字集。過(guò)濾器的主要作用是限制我們的應(yīng)用程序的查詢數(shù)據(jù)。這個(gè)過(guò)濾器的概念并不是什么新概念,如數(shù)據(jù)庫(kù)的視圖也屬于過(guò)濾器范疇。而Hibernate為我們提供的過(guò)濾器是在一個(gè)抽象的層次,它可以做到和不依賴于數(shù)據(jù)庫(kù)的類型,使數(shù)據(jù)訪問(wèn)層只面對(duì)一個(gè)解決方案,那就是Hibernate Filter。當(dāng)然,直接在數(shù)據(jù)庫(kù)中建立視圖也算一種解決方案,但這樣做太不靈活。而Hibernate過(guò)濾器卻能夠在Hibernate會(huì)話的過(guò)程中打開(kāi)或關(guān)閉。另外,另外,Hibernate過(guò)濾器可以傳遞參數(shù),這樣將大大增加Hibernate的靈活性。雖然Hibernate2也提供了過(guò)濾器,但Hibernate3.x提供了一種全新的過(guò)濾器。
    Hibernate3的過(guò)濾器可以進(jìn)行預(yù)定義,并可綁定在類和集合層。那么什么叫預(yù)定義過(guò)濾器呢?就是可以定義象"where"子句的限制性子句,但這些子句是相對(duì)類和不同集合的元素的。除了這些過(guò)濾器條件可以被參數(shù)化外。系統(tǒng)還能決定在運(yùn)行是指定的過(guò)濾器是否應(yīng)該被打開(kāi)以及什么值被傳入過(guò)濾器參數(shù)。
    一、什么時(shí)候使用過(guò)濾器
    為了解釋為什么使用過(guò)濾器,下面讓我們先來(lái)看一個(gè)例子。假設(shè)有一個(gè)管理用戶信息的Web應(yīng)用程序。在當(dāng)前狀態(tài),我們的應(yīng)用程序使用同一個(gè)應(yīng)用接口來(lái)處理所有的用戶信息。但如果最終用戶要求將活動(dòng)用戶和過(guò)期用戶分開(kāi)管理。這些狀態(tài)信息被保存在用戶表的某一列中。對(duì)于這種需求,我們最容易想到的一個(gè)解決方案是重新寫每一個(gè)SELECT HQL查詢語(yǔ)句,也就是在每一個(gè)HQL后加一個(gè)WHERE條件來(lái)過(guò)濾這些數(shù)據(jù)。當(dāng)然,這種方法的復(fù)雜程序取決于你的Web程序是如何建立的,可以很簡(jiǎn)單,也可以很復(fù)雜。但不管是簡(jiǎn)單還是復(fù)雜,都必須得修改我們?cè)?jīng)測(cè)試過(guò)的代碼,這將給我們的程序帶來(lái)非常大的隱患。而使用Hibernate3.x,將會(huì)給我們帶來(lái)另外一個(gè)解決方案。我們將會(huì)為應(yīng)用程序的用戶狀態(tài)創(chuàng)建一個(gè)過(guò)濾器。當(dāng)用戶選擇用戶的狀態(tài)時(shí)(活動(dòng)或過(guò)期),應(yīng)用程序?qū)⒓せ町?dāng)前Hibernate會(huì)話的用戶狀態(tài)過(guò)濾器。這樣以來(lái),所有的SELECT HQL查詢將返回查詢結(jié)果的子集,而我們只需要在Hibernate會(huì)話狀態(tài)和用戶狀態(tài)過(guò)濾器兩個(gè)地方添加代碼,并不需要修改原先的代碼。
    從概念上講,你可以使用WHERE子句在應(yīng)用程序中完成和Hibernate過(guò)濾器同樣的工作。當(dāng)然,我們還可以在數(shù)據(jù)庫(kù)中建立視圖來(lái)完成同樣的工作(但所使用的數(shù)據(jù)庫(kù)必須支持視圖功能)。這三種解決方案都可以通過(guò)一個(gè)或多個(gè)查詢條件來(lái)限制最終結(jié)果。而Hibernate過(guò)濾器的優(yōu)勢(shì)就在于可以隨時(shí)在程序中關(guān)閉或打開(kāi),也就是說(shuō)過(guò)濾器是可編程的,而且過(guò)濾器被定義在Hibernate的映射文件中,這樣將非常容易維護(hù)。當(dāng)然,過(guò)濾器也有不足的地方,主要的不足就是在運(yùn)行時(shí)無(wú)法創(chuàng)建新的過(guò)濾器。而程序在運(yùn)行時(shí),所有的過(guò)濾器必須要在映射文件中被指定。雖然這將大大限制過(guò)濾器的靈活性,但過(guò)濾器支持參數(shù)化。對(duì)于本文的例子,我們可以在映射文件中指定保存用戶狀態(tài)信息的列。我們不需要在映射文件中指定可能的狀態(tài)值,這些在程序運(yùn)行時(shí)都可以指定。接下來(lái)我們就來(lái)看看如何使用Hibernate3.x中的過(guò)濾器來(lái)寫程序。