一个过滤数据的例子
现在假设有一个实体,这个实体跟着“有效的记录”数据库模式。这个实体有多个行,每一行都根据日期不同而不同,也就是说在日期范围内是有效的。一个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过滤器结合,将会发挥出更大的力量。
