filter顾名思义,就是只从数据库查询出满足条件的数据,其实就是select语句中的where条件。student的实体和映射文件如下:
public class Student {
private int id;
private String name;
private int age;
// 省略了setter/getter
....
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Student">
<id name="id" unsaved-value="0">
<generator class="native"></generator>
</id>
<property name="name"></property>
<property name="age" />
<filter name="minAgeFilter">
<![CDATA[
age > :paramAge
]]>
</filter>
<filter name="maxAgeFilter">
<![CDATA[
age < :paramAge
]]>
</filter>
</class>
<filter-def name="minAgeFilter">
<filter-param name="paramAge" type="int" />
</filter-def>
<filter-def name="maxAgeFilter">
<filter-param name="paramAge" type="int" />
</filter-def>
</hibernate-mapping>
我们使用<filter-def>来声明一个filter,使用<filter>来引用一个filter。<filter-def>定义了参数的名称和类型,<filter>定义condition条件。<filter-def>和<filter>通过名称进行关联,这和web.xml中配置servlet是类似的。
在实体映射文件中,声明和引用filter后,我们需要在java代码中显示地打开filter并设置参数。
@Test
public void testQuery() {
Session session = sessionFactory.openSession();
// 开启filter并设置filter的参数
session.enableFilter("minAgeFilter").setParameter("paramAge", 10);
session.enableFilter("maxAgeFilter").setParameter("paramAge", 20);
Query query = session.createQuery("from Student");
@SuppressWarnings("unchecked")
List<Student> results = (List<Student>) query.list();
for (Student each : results) {
Assert.assertTrue(each.getAge() > 10 && each.getAge() < 20);
}
session.close();
}
select
student0_.id as id0_,
student0_._version as column2_0_,
student0_.name as name0_,
student0_.age as age0_
from
Student student0_
where
student0_.age > ?
and student0_.age < ?
可以看到filter起作用了,上面这段代码其实没有什么实际的意义,只是用来演示。使用HQL、SQL或者Criteria查询等,是可以很方便地设置查询条件的,所以filter实际上也并没有什么用处。使用SQL或者HQL等方案,必需将查询条件写死在java代码里,而使用filter是将查询条件写在实体映射文件中的。也就是说filter将一些逻辑从代码中转移到配置文件。
最后一点需要注意下:使用session.load()或者session.get()按照主键查询是不会使用过滤器的。
// cannot use filter
@Test
public void testById() {
Session session = sessionFactory.openSession();
session.enableFilter("minAgeFilter").setParameter("paramAge", 10);
session.enableFilter("maxAgeFilter").setParameter("paramAge", 20);
Student student = (Student) session.get(Student.class, 1);
System.out.println(student);
session.close();
}
@Test
public void testQuery() {
Session session = sessionFactory.openSession();
session.enableFilter("minAgeFilter").setParameter("paramAge", 10);
session.enableFilter("maxAgeFilter").setParameter("paramAge", 20);
Query query = session.createQuery("from Student where id=1");
@SuppressWarnings("unchecked")
List<Student> results = (List<Student>) query.list();
for (Student each : results) {
Assert.assertTrue(each.getAge() > 10 && each.getAge() < 20);
}
session.close();
}