Hibernate過濾器使用竅門
本文向大家介紹Hibernate過濾器,可能好多人還不了解Hibernate過濾器,沒有關(guān)系,看完本文你肯定有不少收獲,希望本文能教會(huì)你更多東西。
Hibernate3新增了對(duì)某個(gè)類或者集合使用預(yù)先定義的Hibernate過濾器條件(filter criteria)的功能。過濾器條件相當(dāng)于定義一個(gè) 非常類似于類和各種集合上的“where”屬性的約束子句,但是過濾器條件可以帶參數(shù)。
應(yīng)用程序可以在運(yùn)行時(shí)決定是否啟用給定的Hibernate過濾器,以及使用什么樣的參數(shù)值。 過濾器的用法很像數(shù)據(jù)庫(kù)視圖,只不過是在應(yīng)用程序中確定使用什么樣的參數(shù)的。
要使用過濾器,必須首先在相應(yīng)的映射節(jié)點(diǎn)中定義。而定義一個(gè)過濾器,要用到位于<hibernate-mapping/> 節(jié)點(diǎn)之內(nèi)的<filter-def/>節(jié)點(diǎn):
- <filter-def name="myFilter">
- <filter-param name="myFilterParam" type="string"/>
- </filter-def>
定義好之后,就可以在某個(gè)類中使用這個(gè)過濾器:
- <class name="myClass" ...>
- ...
- <filter name="myFilter" condition=":myFilterParam = MY_FILTERED_COLUMN"/>
- </class>
也可以在某個(gè)集合使用它:
- <set ...>
- <filter name="myFilter" condition=":myFilterParam = MY_FILTERED_COLUMN"/>
- </set>
可以在多個(gè)類或集合中使用某個(gè)過濾器;某個(gè)類或者集合中也可以使用多個(gè)過濾器。
Session對(duì)象中會(huì)用到的方法有:enableFilter(String filterName), getEnabledFilter(String filterName), 和 disableFilter(String filterName). Session中默認(rèn)是不啟用過濾器的,必須通過Session.enabledFilter()方法顯式的啟用。 該方法返回被啟用的Filter的實(shí)例。以上文定義的過濾器為例:
- session.enableFilter("myFilter").setParameter("myFilterParam", "some-value");
注意,org.hibernate.Filter的方法允許鏈?zhǔn)椒椒ㄕ{(diào)用。(類似上面例子中啟用Filter之后設(shè)定Filter參數(shù)這個(gè)“方法鏈”) Hibernate的其他部分也大多有這個(gè)特性。
下面是一個(gè)比較完整的例子,使用了記錄生效日期模式過濾有時(shí)效的數(shù)據(jù):
- <filter-def name="effectiveDate">
- <filter-param name="asOfDate" type="date"/>
- </filter-def>
- <class name="Employee" ...>
- ...
- <many-to-one name="department" column="dept_id" class="Department"/>
- <property name="effectiveStartDate" type="date" column="eff_start_dt"/>
- <property name="effectiveEndDate" type="date" column="eff_end_dt"/>
- ...
- <!--
- Note that this assumes non-terminal records have an eff_end_dt set to
- a max db date for simplicity-sake
- 注意,為了簡(jiǎn)單起見,此處假設(shè)雇用關(guān)系生效期尚未結(jié)束的記錄的eff_end_dt字段的值等于數(shù)據(jù)庫(kù)最大的日期
- -->
- <filter name="effectiveDate"
- condition=":asOfDate BETWEEN eff_start_dt and eff_end_dt"/>
- </class>
- <class name="Department" ...>
- ...
- <set name="employees" lazy="true">
- <key column="dept_id"/>
- <one-to-many class="Employee"/>
- <filter name="effectiveDate"
- condition=":asOfDate BETWEEN eff_start_dt and eff_end_dt"/>
- </set>
- </class>
定義好后,如果想要保證取回的都是目前處于生效期的記錄,只需在獲取雇員數(shù)據(jù)的操作之前先開啟過濾器即可:
- Session session = ...;
- session.enabledFilter("effectiveDate").setParameter("asOfDate", new Date());
- List results = session.createQuery("from Employee as e where e.salary > :targetSalary")
- .setLong("targetSalary", new Long(1000000))
- .list();
在上面的HQL中,雖然我們僅僅顯式的使用了一個(gè)薪水條件,但因?yàn)閱⒂昧诉^濾器,查詢將僅返回那些目前雇用 關(guān)系處于生效期的,并且薪水高于一百萬(wàn)美刀的雇員的數(shù)據(jù)。
注意:
如果你打算在使用外連接(或者通過HQL或load fetching)的同時(shí)使用過濾器,要注意條件表達(dá)式的方向(左還是右)。 最安全的方式是使用左外連接(left outer joining)。并且通常來說,先寫參數(shù), 然后是操作符,最后寫數(shù)據(jù)庫(kù)字段名。
【編輯推薦】