了解hibernate的特性:filter

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();
}


执行这段代码,是可以通过单元测试的,hibernate发出的SQL如下:
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();
}



已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页