转 http://www.cnblogs.com/yql1986/archive/2011/10/14/2210568.html
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
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(即顾客的年龄为奇数)