Hibernate3高级特性-使用过滤器
Hibernate3高级特性-使用过滤器
Hibernate版本(hibernate-distribution-3.3.1.GA)
Hibernate3 新增了对某个类或集合使用预定义的过滤器条件 (filter criteria) 的功能。过滤器条件相当于定义一个非常类似于类和各种集合上的"where"属性的约束子句,但是过滤器条件可以带参数。应用程序可以在运行时决定是否启用给定的过滤器,以及使用什么样的参数值。过滤器的用法很像数据库视图,只还过是在应用程序员中确定使用什么样的参数。摘自--
http://docs.jboss.org/hibernate/core/3.6/reference/zh-CN/html/filters.html
一、在Hibernate中使用过滤器遵循以下步骤
- Define the filter within the mapping file of the targeted entity (identity the attributes to filter on,and their types)
- Apply the filter on the desired class or collection by indicating it with the <class> or <collection-type> tags
- After obtaining a session with which to perform your actions,enable the appropriate filter , setting any applicable parameters
二 使用 Hibernate3 过滤器

工程结构图(1)
在下面的两个例子中,不贴出 hibernate.cfg.xml和log4j.xml 两个配置文件的代码
example 1: Customer Class Filter Test
假设通过指定顾客的年龄作为查询条件,获取符合查询条件的顾客
1。Customer类文件,Customer 的属性分别是:年龄和姓名 并且每个Customer均有各自的id号
Customer.java
package com.laoyangx.chapter0;
import java.io.Serializable;
public class Customer implements Serializable {
private static final long serialVersionUID = 9210200371341904932L;
private Integer id; //顾客编号
private Integer age; //顾客年龄
private String name; //顾客姓名
public Customer() {
}
public Customer(Integer age, String name) {
this.age = age;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2。 Hibernate的工具类
HibernateUtil.java
package com.laoyangx.chapter0;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
@SuppressWarnings({"rawtypes","unchecked"})
public class HibernateUtil {
private static final SessionFactory sessionFactory;
private static final ThreadLocal localSession = new ThreadLocal();
static {
try{
sessionFactory = new Configuration().configure().buildSessionFactory();
}catch(HibernateException ex){
throw new RuntimeException("sessionFactory :" + ex.getMessage(), ex);
}
}
public static Session currentSession() throws HibernateException {
Session s = (Session) localSession.get();
if (s == null) {
s = sessionFactory.openSession();
localSession.set(s);
}
return s;
}
public static void closeSession() throws HibernateException {
Session s = (Session) localSession.get();
localSession.set(null);
if (s != null)
s.close();
}
}
3。Customer类的数据库映射文件,在配置文件增加了<filter-def>和<filter>两个元素,过滤条件是:顾客年龄大于25
chapter0_customer.hbm.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE hibernate-mapping PUBLIC
3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
4 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
5 <hibernate-mapping>
6 <class name="com.laoyangx.chapter0.Customer" table="T_chapter0_customers" >
7 <id name="id" column="customer_id" type="java.lang.Integer">
8 <generator class="native"/>
9 </id>
10 <property name="age" column="customer_age" type="java.lang.Integer" />
11 <property name="name" column="customer_name" type="java.lang.String" length="25" />
12 <filter name="creationAgeFilter" condition="customer_age>:asOfAge" />
13 </class>
14 <filter-def name="creationAgeFilter">
15 <filter-param name="asOfAge" type="java.lang.Integer"/>
16 </filter-def>
17 </hibernate-mapping>
4。测试
TestFilterDef.java
package com.laoyangx.chapter0;
import java.util.Iterator;
import java.util.List;
import junit.framework.TestCase;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class TestFilterDef extends TestCase {
/**
* 添加顾客
*/
public void addCustomer(){
Session session=HibernateUtil.currentSession();
Transaction transaction=null;
try {
transaction=session.beginTransaction();
for(int i=20;i<30;i++){
session.save(new Customer(i,"customer"+i));
}
transaction.commit();
} catch (HibernateException e) {
if(transaction!=null) transaction.rollback();
e.printStackTrace();
}
finally{
session.close();
}
}
/**
* 通过指定顾客的年龄作为查询条件,获取顾客
*/
public void getCustomerWithAge(){
Session session=HibernateUtil.currentSession();
Transaction transaciton=null;
try {
transaciton=session.beginTransaction();
session.enableFilter("creationAgeFilter").setParameter("asOfAge", new Integer(25)); //顾客年龄大于25
List resultSet=(List)session.createQuery("from Customer").list();
boolean resultNotEmpty=(resultSet!=null)&&resultSet.size()>0;
if(resultNotEmpty){
for(Iterator iter=resultSet.iterator();iter.hasNext();){
Customer customer=(Customer)iter.next();
System.out.println("customer_id-> "+customer.getId()+" customer_name-> "+customer.getName()
+" customer_age-> "+customer.getAge());
}
}
} catch (HibernateException e) {
if(transaciton!=null) transaciton.rollback();
e.printStackTrace();
}
finally{
session.close();
}
}
}
先运行 addCustomer()方法,向数据库中添加测试数据 运行之后,T_chapter0_customers表中的数据显示如下:

随后执行 getCustomerWithAge() 显示结果如下:

example 2: Customer Collection Filter
假设 Customer 与 Order 是一对多的关系 , 每个 Customer可以有多个 Order
1。Customer类文件,Customer 的属性分别是:年龄和姓名 并且每个Customer均有各自的id号。Order类文件 , Order 的属性分别是:日期、是否可见和订单编号。Customer 与 Order 二者之间通过 customer_order_id 进行关联。
Customer.java
package com.laoyangx.chapter0;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
public class Customer implements Serializable {
private static final long serialVersionUID = 9210200371341904932L;
private Integer id; //顾客编号
private Integer age; //顾客年龄
private String name; //顾客姓名
private Set<Order> orders=new HashSet<Order>();
public Customer() { }
public Customer(Integer age, String name) {
this.age = age;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
}
Order.java
package com.laoyangx.chapter0;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Order implements Serializable {
private static final long serialVersionUID = 5266816497026247617L;
private Integer id; //订单编号
private String date; //订单日期
private Boolean visible; //订单状态
private Customer customer; //订单来源
public Order() {}
public Order(Date date, Customer customer,Boolean visible) {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
this.date = sdf.format(date);
this.customer = customer;
this.visible=visible;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date =date;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public Boolean getVisible() {
return visible;
}
public void setVisible(Boolean visible) {
this.visible = visible;
}
}
2。HibernateUtil工具类
HibbernateUitl.java 和 example1 中的 HibernateUitl.java 一样
3。Customer类的数据库映射文件,在配置文件增加 两个<filter-def>和<filter>,过滤条件是:订单的visible属性为true且顾客年龄大于25
chapter0_customer.hbm.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE hibernate-mapping PUBLIC
3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
4 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
5 <hibernate-mapping>
6 <class name="com.laoyangx.chapter0.Customer" table="T_chapter0_customers" >
7 <id name="id" column="customer_id" type="java.lang.Integer">
8 <generator class="native"/>
9 </id>
10 <property name="age" column="customer_age" type="java.lang.Integer" />
11 <property name="name" column="customer_name" type="java.lang.String" length="25" />
12
13 <set name="orders" inverse="true" cascade="all">
14 <key column="customer_order_id" />
15 <one-to-many class="com.laoyangx.chapter0.Order"/>
16 <filter name="creationVisibleFilter" condition="order_visible=:asOfVisible" />
17 </set>
18 <filter name="creationAgeFilter" condition="customer_age>:asOfAge" />
19 </class>
20
21 <filter-def name="creationAgeFilter">
22 <filter-param name="asOfAge" type="java.lang.Integer"/>
23 </filter-def>
24
25 <filter-def name="creationVisibleFilter">
26 <filter-param name="asOfVisible" type="java.lang.Boolean"/>
27 </filter-def>
28
29 </hibernate-mapping>
chapter0_order.hbm.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE hibernate-mapping PUBLIC
3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
4 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
5 <hibernate-mapping>
6 <class name="com.laoyangx.chapter0.Order" table="T_chapter0_orders" >
7 <id name="id" column="order_id" type="java.lang.Integer">
8 <generator class="native"/>
9 </id>
10 <property name="date" column="order_date" type="java.lang.String" length="10" />
11 <property name="visible" column="order_visible" type="java.lang.Boolean" />
12 <many-to-one name="customer" class="com.laoyangx.chapter0.Customer" column="customer_order_id"></many-to-one>
13 </class>
14 </hibernate-mapping>
5。测试
TestFilterDef.java
package com.laoyangx.chapter0;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import junit.framework.TestCase;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class TestFilterDef extends TestCase {
/**
* 添加顾客和订单号,用于测试
*/
public void fillData(){
Session session=HibernateUtil.currentSession();
Transaction transaction=null;
try {
transaction=session.beginTransaction();
for(int i=20;i<30;i++){
Customer customer=new Customer(i,"customer"+i);
boolean visible=(0==i%2)?false:true; //当顾客的年龄为偶数是 visible=false 反之为 true
Order order=new Order(new Date(),customer,visible);
customer.getOrders().add(order);
session.save(customer);
}
transaction.commit();
} catch (HibernateException e) {
if(transaction!=null) transaction.rollback();
e.printStackTrace();
}
finally{
session.close();
}
}
/**
* 通过指定顾客的年龄作为查询条件,获取顾客
*/
public void getCustomerWithAge(){
Session session=HibernateUtil.currentSession();
Transaction transaciton=null;
try {
transaciton=session.beginTransaction();
session.enableFilter("creationVisibleFilter").setParameter("asOfVisible",true);
session.enableFilter("creationAgeFilter").setParameter("asOfAge", new Integer(25));
List resultSet=(List)session.createQuery("from Customer").list();
Boolean resultNotEmpty=(resultSet!=null)&&resultSet.size()>0;
if(resultNotEmpty){
for(Iterator iter=resultSet.iterator();iter.hasNext();) {
Customer customer=(Customer)iter.next();
Set<Order> orders=customer.getOrders();
Boolean orderIsNullOrEmpty=(orders!=null)&&orders.size()>0;
if(orderIsNullOrEmpty){
System.out.println("customer_id-> "+customer.getId()+" customer_name-> "+customer.getName()
+" customer_age-> "+customer.getAge());
for(Iterator<Order> i=orders.iterator();i.hasNext();){
Order order=(Order)i.next();
System.out.println("order_id-> "+order.getId()+" order_date-> "+order.getDate());
}
}
System.out.println("-----------------------------");
}
}
} catch (HibernateException e) {
if(transaciton!=null) transaciton.rollback();
e.printStackTrace();
}
finally{
session.close();
}
}
}
先运行 fillData()方法 ,向数据库中添加测试数据 运行之后 t_chapter0_customers和t_chapter0_orders这两张表中的数据如下:


order_visible 生成的规律是:顾客的年龄为偶数时候 order_visible=false 反之为true
运行 getCustomerWithAge() 方法 查询条件为顾客中年龄大于25且 order_visible为true(即顾客的年龄为奇数)


浙公网安备 33010602011771号