首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Hibernate 3.x 過濾器進階應用實戰

     編輯:Java 相關知識

為什麼需要過濾器?

許多應用不需要一次查詢資料表所有資料。例如用戶管理系統需區分「活躍用戶」與「過期用戶」,狀態儲存在用戶表某欄位。傳統做法是在每條 HQL 追加 WHERE 條件,但這會修改大量既有代碼,風險高且難維護。Hibernate 3.x 提供的過濾器 (Filter) 可在映射檔預先定義條件,並在 Session 執行期動態啟用/停用、傳遞參數,實現零侵入式查詢限制。

過濾器核心優勢

  • 可程式化控制:Session 中隨時啟用/停用
  • 定義於映射檔:集中維護,易於管理
  • 支援參數化:運行時傳入動態值
  • 不依賴特定資料庫:跨資料庫可攜
  • 可綁定於類或集合層級

缺點:運行時無法動態創建新過濾器,必須在映射檔預先定義。

過濾器配置詳解

1. 定義過濾器

在 <hibernate-mapping> 中使用 <filter-def>:

<filter-def name="myFilter">
    <filter-param name="myFilterParam" type="string"/>
</filter-def>

2. 綁定至實體類

<class name="myClass" ...>
    <filter name="myFilter" condition=":myFilterParam = my_filtered_column"/>
</class>

3. 綁定至集合

<set ...>
    <filter name="myFilter" condition=":myFilterParam = my_filtered_column"/>
</set>

Session API 操作過濾器

  • enableFilter(String filterName):啟用並回傳 Filter 實例
  • getEnabledFilter(String filterName):取得已啟用的 Filter
  • disableFilter(String filterName):停用過濾器

預設過濾器關閉,需顯式啟用並設定參數:

session.enableFilter("myFilter").setParameter("myFilterParam", "some-value");

實戰範例

範例一:依生效日期篩選雇員記錄

雇員資料含 effectiveStartDate、effectiveEndDate,需查詢指定日期生效的記錄。

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

<class name="Employee">
    <property name="effectiveStartDate" type="date" column="eff_start_dt"/>
    <property name="effectiveEndDate" type="date" column="eff_end_dt"/>
    <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>

啟用過濾器:

Session session = ...;
session.enableFilter("effectiveDate").setParameter("asOfDate", new Date());
List results = session.createQuery("from Employee e where e.salary > :targetSalary")
    .setLong("targetSalary", 1000000L)
    .list(); // 僅返回當前生效且薪資超過百萬的雇員

範例二:基於存取層級的資料安全過濾

敏感實體 Opportunity 有 accessLevel 欄位,用戶只能看權限內的資料。

<filter-def name="accessLevel">
    <filter-param name="userLevel" type="int"/>
</filter-def>

<class name="Opportunity">
    <property name="accessLevel" type="int" column="access_lvl"/>
    <filter name="accessLevel" condition="access_lvl <= :userLevel"/>
</class>

<class name="Region">
    <set name="opportunities" lazy="true">
        <key column="region_id"/>
        <one-to-many class="Opportunity"/>
        <filter name="accessLevel" condition="access_lvl <= :userLevel"/>
    </set>
</class>

啟用過濾器:

User user = ...;
Session session = ...;
session.enableFilter("accessLevel").setParameter("userLevel", user.getAccessLevel());
Region region = (Region) session.get(Region.class, "EMEA");
int count = region.getOpportunities().size(); // 自動過濾至用戶權限內的機會

結語

Hibernate 3.x 過濾器提供強大且靈活的查詢限制機制,透過映射檔集中定義、Session 動態控制,極大降低業務邏輯與查詢條件的耦合。結合攔截器、Web Filter 等技術,可構建更完善的資料存取控制體系。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved