四、实例
1. 一个过滤数据的例子
现在假设有一个实体,这个实体跟着“有效的记录”数据库模式。这个实体有多个行,每一行都根据日期不同而不同,也就是说在日期范围内是有效的。一个employment记录将是一个非常好的例子,因为employees可以来或去或再回来。现在我们开发一个带UI的程序,这个程序需要处理employment数据的当前记录。为了使用新的过滤器特性达到这个目的。我们首先需要定义这个过滤器,然后将它附着在Employee类上。
<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"/>
...
<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.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中,即使我们只给出一个salary约束条件,由于我们已经打开发过滤器,也只会得到当前活动的比一百万多的雇员。
2. 安全的实例
假设我们有一个应用程序,这个程序给每一个用户分配一个访问权限。在这其间,系统中一些敏感的实体被分配给了某些访问层次。因此,一个用户在它所属的访问层中应该可以看到更多的东西。在本例子中我们就要通过过滤器来过滤某一个访问层次中的实体。下面让我们来定义过滤器。
<filter-def name="accessLevel">
<filter-param name="userLevel" type="int"/>
</filter-def>
<class name="Opportunity" ...>
...
<many-to-one name="region" column="region_id" class="Region"/>
<property name="amount" type="Money">
<column name="amt"/>
<cloumn name="currency"/>
</property>
<property name="accessLevel" type="int" column="access_lvl"/>
...
<filter name="accessLevel">= access_lvl]]>
</class>
<class name="Region" ...>
...
<set name="opportunities" lazy="true">
<key column="region_id"/>
<one-to-many class="Opportunity"/>
<filter name="accessLevel">= access_lvl]]>
</set>
...
</class>
接下来,让我们来打开过滤器。
User user = ...;
Session session = ...;
session.enableFilter("accessLevel").setParameter("userLevel", user.getAccessLevel());
下面的代码是一个正在装载的区域,它将过滤当前用户访问层的集合以得到一个子集。
Region region = (Region) session.get(Region.class, "EMEA");
region.getOpportunities().size();
四、结论
本文简单介绍了Hibernate3.x的使用方法,并给出了一些实例。虽然这些例子很简单,但却使我们对Hibernate3.x过滤器的强大有了更深的认识。我们通过上面的例子也许会有更多好的想法,如果能将它们和不同的拦截方法,如Web过滤器结合,将会发挥出更大的力量。