posts - 495,  comments - 11,  trackbacks - 0

          數據過濾并不是一種常規的數據查詢方法,而是一種整體的篩選方法。數據過濾也可對數據進行篩選,因此,將其放在Hibernate的數據查詢框架中介紹。

          如果一旦啟用了數據過濾器,則不管數據查詢,還是數據加載,該過濾器將自動作用于所有數據,只有滿足過濾條件的記錄才會被選出來。

          過濾器與定義在類和集合映射文件上的“where”屬性非常相似。它們的區別是過濾器可以帶參數,應用程序可以在運行時決定是否啟用指定的過濾器,以及使用什么樣的參數值。而映射文件上的“where”屬性將一直生效,且無法動態傳入參數。

          過濾器的用法很像數據庫視圖,區別是視圖在數據庫中已經定義完成,而過濾器則還需在應用程序中確定參數值。

          過濾器的使用分成三步:

          (1)定義過濾器。使用filter-def元素定義過濾器;

          (2)使用過濾器。使用filter元素使用過濾器;

          (3)在代碼中啟用過濾器。

          前兩個步驟都是在Hibernate的映射文件中完成的,其中filter-def是hibernate-mapping元素的子元素,而filter元素是class集合元素的子元素。

          filter-def元素用于定義一個過濾器,filter則將指定的過濾器應用到指定的持久化類。

          一個持久化類或集合可以使用多個過濾器,而一個過濾器也可以作用于多個持久化類或集合。

          看下面的映射文件示例:

          <?xml version="1.0"?>

          <!-- Hibernate配置文件的文件頭,包含DTD等信息 -->

          <!DOCTYPE hibernate-mapping

          ??? PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

          ??? "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

          <!-- Hibernate 配置文件的根元素 -->

          <hibernate-mapping >

          ??? <!-- 每個class元素定義一個持久化類 -->

          ??? <class name="Category" table="category">

          ??????? <!-- 定義標識屬性 -->

          ??? ??? <id name="id" column="category_id" >

          ??? ??????? <!-- 指定主鍵生成器策略 -->

          ??????? ??? <generator class="native"/>

          ??? ??? </id>

          ??????? <!-- 映射name屬性 -->

          ??? ??? <property name="name" type="string"/>

          ??????? <!-- 映射effectiveStartDate屬性 -->

          ??? ??? <property name="effectiveStartDate" column="eff_start_date"

          ??????? type="java.util.Date"/>

          ??????? <!-- 映射effectiveEndDate屬性 -->

          ??? ??? <property name="effectiveEndDate" column="eff_end_date"

          ??????? type="java.util.Date"/>

          ??????? <!-- 映射N-N關聯屬性 -->

          ??? ??? <set cascade="none" inverse="true" name="products"

          ??????? table="product_category">

          ??????????? <!-- 定義關聯屬性的key,對應連接表中的外鍵列 -->

          ??????? ??? <key column="category_id"/>

          ??????????? <!-- 定義關聯屬性 -->

          ??????? ??? <many-to-many column="product_id" class="Product"/>

          ??? ??? </set>

          ??????? <!-- 使用過濾器,并設置過濾器條件 -->

          ??? ??? <filter name="effectiveDate" condition=":asOfDate BETWEEN

          ??????? eff_start_date and eff_end_date"/>

          ??? </class>

          ??? <!-- 定義第二個持久化類 -->

          ??? <class name="Product" table="product">

          ??????? <!-- 定義標識屬性 -->

          ??? ??? <id name="id" column="product_id" >

          ??????????? <!-- 指定主鍵生成器策略 -->

          ??????? ??? <generator class="native"/>

          ??? ??? </id>

          ??????? <!-- 映射name屬性 -->

          ??? ??? <property name="name" type="string"/>

          ??????? <!-- 映射stockNumber屬性 -->

          ??? ??? <property name="stockNumber" column="stock_number" type="int"/>

          ??????? <!-- 映射effectiveStartDate屬性 -->

          ??? ??? <property name="effectiveStartDate" column="eff_start_date"

          ??????? type="java.util.Date"/>

          ??????? <!-- 映射effectiveEndDate屬性 -->

          ??? ??? <property name="effectiveEndDate" column="eff_end_date"

          ??????? type="java.util.Date"/>

          ??????? <!-- 映射N-N關聯屬性 -->

          ??????? <set cascade="all" name="categories" fetch="join"

          ??????? table="product_category" >

          ??????????? <!-- 定義關聯屬性的key,對應連接表中的外鍵列 -->

          ??????? ??? <key column="product_id"/>

          ??????????? <!-- 定義關聯屬性 -->

          ??????? ??? <many-to-many column="category_id"

          ??????????????????????? class="Category" fetch="join">

          ??????????????? <!-- 對關聯屬性使用第一個過濾器 -->

          ??? ??????????? <filter name="effectiveDate"

          ??????????????????? condition=":asOfDate BETWEEN eff_start_date and

          ??????????????????? eff_end_date"/>

          ??????????????? <!-- 對關聯屬性使用第二個過濾器 -->

          ??????????? ??? <filter name="category" condition="category_id = :catId"/>

          ??????????? </many-to-many>

          ??? ??? </set>

          ??????? <filter name="effectiveDate" condition=":asOfDate BETWEEN

          ??????? eff_start_date AND eff_end_date"/>

          ??? </class>

          ??? <!-- 定義第一個過濾器,該過濾器包含一個date類型的參數 -->

          ??? <filter-def name="effectiveDate">

          ??????? <filter-param name="asOfDate" type="date"/>

          ??? </filter-def>

          ??? <!-- 定義第二個過濾器,該過濾器包含一個long類型的參數 -->

          ??? <filter-def name="category">

          ??????? <filter-param name="catId" type="long"/>

          ??? </filter-def>

          </hibernate-mapping>

          在上面的配置文件中,定義了兩個過濾器,過濾器的定義通過filter-def元素完成。定義過濾器時,只需要指定過濾器的名字,以及過濾器的參數即可。如Java里的一個方法聲明,只有方法名和參數列表,具體的方法實現是沒有的。

          過濾器的過濾條件是使用過濾器時才確定的,使用過濾器通過filter元素確定,filter的condition屬性用于確定過濾條件,滿足該條件的記錄才會被抓取到。

          系統默認不啟用過濾器,必須顯式通過enableFilter(String filterName)才可以啟用過濾器,該方法返回一個Filter實例,Filter包含setParameter方法用于為過濾器參數賦值。

          一旦啟用了過濾器,過濾器在整個Session內有效,所有的數據加載將自動應用該過濾條件,直到調用disableFilter方法。

          看下面的使用過濾器的示例代碼:

          private void test() throws Exception

          {

          ??? //獲取Hibernate Session對象

          ??? Session session = HibernateUtil.currentSession();

          ??? //開始事務

          ??? Transaction tx = session.beginTransaction();

          ??? //啟用第一個過濾器

          ??? session.enableFilter("effectiveDate")

          ??????????? //為過濾器設置參數

          ??????????? .setParameter("asOfDate", new Date());

          ??? //啟動第二個過濾器

          ??? session.enableFilter("category")

          ??????????? //為過濾器設置參數

          ??????????? .setParameter("catId", new Long(2));

          ??? //執行查詢,該查詢沒有任何的查詢條件

          ??? Iterator results = session.createQuery("from Product as p")

          ????????????????????????? .iterate();

          ??? //遍歷結果集

          ??? while (results.hasNext())

          ??? {

          ??????? Product p = (Product)results.next();

          ??????? System.out.println(p.getName());

          ??????? //此處獲取Product關聯的種類,過濾器也將自動應用過濾

          ??????? Iterator it = p.getCategories().iterator();

          ??????? System.out.println(p.getCategories().size());

          ??????? while (it.hasNext())

          ??????? {

          ??????????? Category c = (Category)it.next();

          ??????????? System.out.println(c.getName());

          ??????? }

          ??? }

          ??? tx.commit();

          ??? HibernateUtil.closeSession();

          }

          通過使用過濾器定義常用的數據篩選規則,如果是臨時的數據篩選,還是使用常規查詢比較好。對于從前使用行列表達式視圖的地方,此處可以考慮使用過濾器。

          posted on 2009-07-19 09:08 jadmin 閱讀(120) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 溧水县| 两当县| 武平县| 邯郸县| 龙江县| 桂林市| 阿拉善右旗| 乌兰浩特市| 和政县| 修武县| 新民市| 明水县| 长垣县| 固镇县| 武清区| 洞口县| 中牟县| 福州市| 新沂市| 开鲁县| 梅河口市| 远安县| 潞西市| 融水| 财经| 肇东市| 临沧市| 新巴尔虎右旗| 宿迁市| 玛曲县| 凤阳县| 平凉市| 金乡县| 鹤岗市| 邓州市| 天峻县| 岫岩| 成安县| 平泉县| 沾化县| 会同县|