`
- 浏览:
361185 次
- 性别:
- 来自:
北京
-
-
具有一个直观的、可扩展的条件查询API是Hibernate的特色。
-
-
15.1
. 创建一个Criteria 实例
-
org.hibernate.Criteria接口表示特定持久类的一个查询。Session是 Criteria实例的工厂。
-
-
Criteria crit = sess.createCriteria(Cat.class
);
-
crit.setMaxResults(50
);
-
List cats = crit.list();
-
15.2
. 限制结果集内容
-
一个单独的查询条件是org.hibernate.criterion.Criterion 接口的一个实例。org.hibernate.criterion.Restrictions类 定义了获得某些内置Criterion类型的工厂方法。
-
-
List cats = sess.createCriteria(Cat.class
)
-
.add( Restrictions.like("name"
,
"Fritz%"
) )
-
.add( Restrictions.between("weight"
, minWeight, maxWeight) )
-
.list();
-
约束可以按逻辑分组。
-
-
List cats = sess.createCriteria(Cat.class
)
-
.add( Restrictions.like("name"
,
"Fritz%"
) )
-
.add( Restrictions.or(
-
Restrictions.eq( "age"
,
new
Integer(
0
) ),
-
Restrictions.isNull("age"
)
-
) )
-
.list();
-
List cats = sess.createCriteria(Cat.class
)
-
.add( Restrictions.in( "name"
,
new
String[] {
"Fritz"
,
"Izi"
,
"Pk"
} ) )
-
.add( Restrictions.disjunction()
-
.add( Restrictions.isNull("age"
) )
-
.add( Restrictions.eq("age"
,
new
Integer(
0
) ) )
-
.add( Restrictions.eq("age"
,
new
Integer(
1
) ) )
-
.add( Restrictions.eq("age"
,
new
Integer(
2
) ) )
-
) )
-
.list();
-
Hibernate提供了相当多的内置criterion类型(Restrictions 子类), 但是尤其有用的是可以允许你直接使用SQL。
-
-
List cats = sess.createCriteria(Cat.class
)
-
.add( Restrictions.sql("lower({alias}.name) like lower(?)"
,
"Fritz%"
, Hibernate.STRING) )
-
.list();
-
{alias}占位符应当被替换为被查询实体的列别名。
-
-
Property实例是获得一个条件的另外一种途径。你可以通过调用Property.forName() 创建一个Property。
-
-
Property age = Property.forName("age"
);
-
List cats = sess.createCriteria(Cat.class
)
-
.add( Restrictions.disjunction()
-
.add( age.isNull() )
-
.add( age.eq( new
Integer(
0
) ) )
-
.add( age.eq( new
Integer(
1
) ) )
-
.add( age.eq( new
Integer(
2
) ) )
-
) )
-
.add( Property.forName("name"
).in(
new
String[] {
"Fritz"
,
"Izi"
,
"Pk"
} ) )
-
.list();
-
15.3
. 结果集排序
-
你可以使用org.hibernate.criterion.Order来为查询结果排序。
-
-
List cats = sess.createCriteria(Cat.class
)
-
.add( Restrictions.like("name"
,
"F%"
)
-
.addOrder( Order.asc("name"
) )
-
.addOrder( Order.desc("age"
) )
-
.setMaxResults(50
)
-
.list();
-
List cats = sess.createCriteria(Cat.class
)
-
.add( Property.forName("name"
).like(
"F%"
) )
-
.addOrder( Property.forName("name"
).asc() )
-
.addOrder( Property.forName("age"
).desc() )
-
.setMaxResults(50
)
-
.list();
-
15.4
. 关联
-
你可以使用createCriteria()非常容易的在互相关联的实体间建立 约束。
-
-
List cats = sess.createCriteria(Cat.class
)
-
.add( Restrictions.like("name"
,
"F%"
)
-
.createCriteria("kittens"
)
-
.add( Restrictions.like("name"
,
"F%"
)
-
.list();
-
注意第二个 createCriteria()返回一个新的 Criteria实例,该实例引用kittens 集合中的元素。
-
-
接下来,替换形态在某些情况下也是很有用的。
-
-
List cats = sess.createCriteria(Cat.class
)
-
.createAlias("kittens"
,
"kt"
)
-
.createAlias("mate"
,
"mt"
)
-
.add( Restrictions.eqProperty("kt.name"
,
"mt.name"
) )
-
.list();
-
(createAlias()并不创建一个新的 Criteria实例。)
-
-
Cat实例所保存的之前两次查询所返回的kittens集合是 没有被条件预过滤的。如果你希望只获得符合条件的kittens, 你必须使用returnMaps()。
-
-
List cats = sess.createCriteria(Cat.class
)
-
.createCriteria("kittens"
,
"kt"
)
-
.add( Restrictions.eq("name"
,
"F%"
) )
-
.returnMaps()
-
.list();
-
Iterator iter = cats.iterator();
-
while
( iter.hasNext() ) {
-
Map map = (Map) iter.next();
-
Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);
-
Cat kitten = (Cat) map.get("kt"
);
-
}
-
15.5
. 动态关联抓取
-
你可以使用setFetchMode()在运行时定义动态关联抓取的语义。
-
-
List cats = sess.createCriteria(Cat.class
)
-
.add( Restrictions.like("name"
,
"Fritz%"
) )
-
.setFetchMode("mate"
, FetchMode.EAGER)
-
.setFetchMode("kittens"
, FetchMode.EAGER)
-
.list();
-
这个查询可以通过外连接抓取mate和kittens。 查看第 19.1
节 “ 抓取策略(Fetching strategies) ”可以获得更多信息。
-
-
15.6
. 查询示例
-
org.hibernate.criterion.Example类允许你通过一个给定实例 构建一个条件查询。
-
-
Cat cat = new
Cat();
-
cat.setSex('F'
);
-
cat.setColor(Color.BLACK);
-
List results = session.createCriteria(Cat.class
)
-
.add( Example.create(cat) )
-
.list();
-
版本属性、标识符和关联被忽略。默认情况下值为null
的属性将被排除。
-
-
你可以自行调整Example使之更实用。
-
-
Example example = Example.create(cat)
-
.excludeZeroes()
-
.excludeProperty("color"
)
-
.ignoreCase()
-
.enableLike();
-
List results = session.createCriteria(Cat.class
)
-
.add(example)
-
.list();
-
你甚至可以使用examples在关联对象上放置条件。
-
-
List results = session.createCriteria(Cat.class
)
-
.add( Example.create(cat) )
-
.createCriteria("mate"
)
-
.add( Example.create( cat.getMate() ) )
-
.list();
-
15.7
. 投影(Projections)、聚合(aggregation)和分组(grouping)
-
org.hibernate.criterion.Projections是 Projection 的实例工厂。我们通过调用 setProjection()应用投影到一个查询。
-
-
List results = session.createCriteria(Cat.class
)
-
.setProjection( Projections.rowCount() )
-
.add( Restrictions.eq("color"
, Color.BLACK) )
-
.list();
-
List results = session.createCriteria(Cat.class
)
-
.setProjection( Projections.projectionList()
-
.add( Projections.rowCount() )
-
.add( Projections.avg("weight"
) )
-
.add( Projections.max("weight"
) )
-
.add( Projections.groupProperty("color"
) )
-
)
-
.list();
-
在一个条件查询中没有必要显式的使用 "group by"
。某些投影类型就是被定义为 分组投影,他们也出现在SQL的group by子句中。
-
-
你可以选择把一个别名指派给一个投影,这样可以使投影值被约束或排序所引用。下面是两种不同的实现方式:
-
-
List results = session.createCriteria(Cat.class
)
-
.setProjection( Projections.alias( Projections.groupProperty("color"
),
"colr"
) )
-
.addOrder( Order.asc("colr"
) )
-
.list();
-
List results = session.createCriteria(Cat.class
)
-
.setProjection( Projections.groupProperty("color"
).as(
"colr"
) )
-
.addOrder( Order.asc("colr"
) )
-
.list();
-
alias()和as()方法简便的将一个投影实例包装到另外一个 别名的Projection实例中。简而言之,当你添加一个投影到一个投影列表中时 你可以为它指定一个别名:
-
-
List results = session.createCriteria(Cat.class
)
-
.setProjection( Projections.projectionList()
-
.add( Projections.rowCount(), "catCountByColor"
)
-
.add( Projections.avg("weight"
),
"avgWeight"
)
-
.add( Projections.max("weight"
),
"maxWeight"
)
-
.add( Projections.groupProperty("color"
),
"color"
)
-
)
-
.addOrder( Order.desc("catCountByColor"
) )
-
.addOrder( Order.desc("avgWeight"
) )
-
.list();
-
List results = session.createCriteria(Domestic.class
,
"cat"
)
-
.createAlias("kittens"
,
"kit"
)
-
.setProjection( Projections.projectionList()
-
.add( Projections.property("cat.name"
),
"catName"
)
-
.add( Projections.property("kit.name"
),
"kitName"
)
-
)
-
.addOrder( Order.asc("catName"
) )
-
.addOrder( Order.asc("kitName"
) )
-
.list();
-
你也可以使用Property.forName()来表示投影:
-
-
List results = session.createCriteria(Cat.class
)
-
.setProjection( Property.forName("name"
) )
-
.add( Property.forName("color"
).eq(Color.BLACK) )
-
.list();
-
List results = session.createCriteria(Cat.class
)
-
.setProjection( Projections.projectionList()
-
.add( Projections.rowCount().as("catCountByColor"
) )
-
.add( Property.forName("weight"
).avg().as(
"avgWeight"
) )
-
.add( Property.forName("weight"
).max().as(
"maxWeight"
) )
-
.add( Property.forName("color"
).group().as(
"color"
)
-
)
-
.addOrder( Order.desc("catCountByColor"
) )
-
.addOrder( Order.desc("avgWeight"
) )
-
.list();
-
15.8
. 离线(detached)查询和子查询
-
DetachedCriteria类使你在一个session范围之外创建一个查询,并且可以使用任意的 Session来执行它。
-
-
DetachedCriteria query = DetachedCriteria.forClass(Cat.class
)
-
.add( Property.forName("sex"
).eq(
'F'
) );
-
-
Session session = ....;
-
Transaction txn = session.beginTransaction();
-
List results = query.getExecutableCriteria(session).setMaxResults(100
).list();
-
txn.commit();
-
session.close();
-
DetachedCriteria也可以用以表示子查询。条件实例包含子查询可以通过 Subqueries或者Property获得。
-
-
DetachedCriteria avgWeight = DetachedCriteria.forClass(Cat.class
)
-
.setProjection( Property.forName("weight"
).avg() );
-
session.createCriteria(Cat.class
)
-
.add( Property.forName("weight).gt(avgWeight) )
-
.list();
-
DetachedCriteria weights = DetachedCriteria.forClass(Cat.class
)
-
.setProjection( Property.forName("weight"
) );
-
session.createCriteria(Cat.class
)
-
.add( Subqueries.geAll("weight"
, weights) )
-
.list();
-
甚至相互关联的子查询也是有可能的:
-
-
DetachedCriteria avgWeightForSex = DetachedCriteria.forClass(Cat.class
,
"cat2"
)
-
.setProjection( Property.forName("weight"
).avg() )
-
.add( Property.forName("cat2.sex"
).eqProperty(
"cat.sex"
) );
-
session.createCriteria(Cat.class
,
"cat"
)
-
.add( Property.forName("weight).gt(avgWeightForSex) )
-
.list();
-
-
-
-
-
把HSQL语句用Criteria代替,感觉更加美观一点,而且还支持中文,要是HSQL想支持中文,你得使用占位符来设置,具体可参照:http:
-
-
那么Criteria的用法是这样的:
-
-
public
Collection findCriteria(
final
DetachedCriteria dc,
final
IPage page) {
-
return
(List) getHibernateTemplate().execute(
new
HibernateCallback(){
-
public
Object doInHibernate(Session session)
throws
HibernateException, SQLException {
-
Criteria c = dc.getExecutableCriteria(session);
-
-
page.setTotalCount(((Integer) c.setProjection(Projections.rowCount()).uniqueResult()).intValue());
-
c.setProjection(null
);
-
c.setResultTransformer(Criteria.ROOT_ENTITY);
-
c.setFirstResult(page.getBeginIndex());
-
c.setMaxResults(page.getPageSize());
-
return
c.list();
-
}
-
}, true
);
-
}
-
-
其中的参数true
表
示要Spring强制传入SessionImpl,而不是传入Proxy代理
类,page.setTotalCount(((Integer) c.setProjection(Projections.rowCount()).uniqueResult()).intValue());
-
c.setProjection(null
); 目的是为了获得行数,并设置投影为空,为的是返回List出来,如果不设置setProjection(
null
)的话,c.list将返回的是行数(
int
型),
而不是所要查询的数据库信息。但是Criteria的ResultTransformer会变成
PassThroughResultTransformer,criteria.list的时候可能结果会跟理想的不一样。所以我们还要再
c.setResultTransformer(Criteria.ROOT_ENTITY);把结果以Entity的形式返回,而不是Object[]
的形式返回。具体的ResultTransformer可以google一下。
-
-
测试代码如下:
-
-
public
void
testCriteria() {
-
DetachedCriteria dc = DetachedCriteria.forClass(User.class
);
-
dc.add(Restrictions.eq("name"
,
"user"
)).add(Restrictions.like(
"description"
,
"%主管人员%"
));
-
IPage page = new
Page();
-
page.setCurrentPage(1
);
-
page.setPageSize(10
);
-
Collection list = _userDAO.findCriteria(dc, page);
-
assertNotNull(list);
-
assertEquals(1
, list.size());
-
}
-
-
来源:http:
-
-
http://qingzhuang.iteye.com/blog/33418
分享到:
Global site tag (gtag.js) - Google Analytics
相关推荐
在上面的代码中,我们首先创建了一个 Criteria 对象,然后使用 `Restrictions.like()` 方法创建了一个条件对象,最后使用 `add()` 方法将条件添加到 Criteria 对象中,并使用 `list()` 方法来获取查询结果。...
下面将详细解释Criteria API的核心概念和用法。 Criteria API的主要优势在于它允许程序在运行时构造查询,这意味着可以在不硬编码SQL的情况下,根据业务逻辑的变化灵活地调整查询条件。这对于维护和扩展应用程序...
以下是一些使用Criteria API的基本用法: 1. 创建Criteria实例: ```java Criteria criteria = session.createCriteria(User.class); ``` 2. 添加查询条件: ```java criteria.add(Restrictions.eq("username...
若要对查询结果进行排序,可以使用`Criteria` 的`addOrder()` 方法。例如,按价格降序排列: ```java Criteria criteria = session.createCriteria(Books.class); criteria.addOrder(Order.desc("price")); List...
### Criteria使用方法详解 #### 一、概述 在软件开发过程中,尤其是涉及到数据库操作的应用程序中,查询语言的灵活性和效率对于项目的成功至关重要。Hibernate作为Java领域中最流行的ORM(Object Relational ...
使用 Criteria 进行查询,主要要清晰的是 Hibernate 提供了那些类和方法来满足开发中查询条件的创建和组装。Criteria crit = session.createCriteria(User.class); crit.add(Restrictions.eq("name", "John")); List...
**关联映射Hibernate的Criteria用法详解** 在Java开发中,Hibernate作为一种强大的对象关系映射(ORM)框架,极大地简化了数据库操作。其中,Criteria API是Hibernate提供的一个动态查询工具,它允许开发者以面向...
2. **排序**:`Criteria`允许你指定查询结果的排序规则,使用`addOrder`方法添加`Order`实例。 ```java criteria.addOrder(Order.asc("name")); criteria.addOrder(Order.desc("groupId")); ``` 3. **分页**:...
2. **添加限制条件**:使用Criteria的add()方法添加谓词,如EqRestriction(等于)、LeRestriction(小于等于)等,来定义查询的过滤条件。 3. **添加排序**:如果需要对结果进行排序,可以使用Criteria的...
这种API的使用方法更加面向对象,减少了硬编码SQL的风险,同时提高了代码的可读性和可维护性。下面我们将通过几个关键概念来深入理解Criteria查询。 1. **Session**: Hibernate的核心接口,用于与数据库进行交互。...
本文将对 Hibernate 中 Criteria 的用法进行总结,涵盖 Criteria 和 DetachedCriteria 的差异、Criterion 和 Projection 的使用方法等。 Hibernate 设计了 CriteriaSpecification 作为 Criteria 的父接口,下面提供...
本文详细介绍了 Hibernate Criteria API 的使用方法,包括基本概念、创建查询实例、添加查询条件以及示例代码分析。通过 Criteria API 可以轻松地构建复杂的查询条件,并且由于其类型安全的特性,可以有效减少编程...
- **使用场景**:`Criteria` 适用于即时查询,而 `DetachedCriteria` 更适合跨层传递查询条件。 - **灵活性**:`DetachedCriteria` 提供了更大的灵活性,可以在不同层之间传递而不会丢失查询状态。 #### 三、`...
3. **添加模糊查询条件**:使用Criteria的add(Restrictions.like())方法,其中参数分别为属性名和模糊查询字符串。注意,字符串中的“%”符号表示任意字符匹配,可以根据需求放在字符串的开头、结尾或中间。 4. **...
通过理解并熟练掌握`Criteria`、`DetachedCriteria`、`Criterion`和`Projection`等核心概念及其使用方法,可以显著提升数据库操作的效率和代码的可维护性。在实际项目中,结合Spring框架的便利性,开发者能够更加...
在Java持久层框架Hibernate中,Criteria API是一种动态构建SQL查询的方法,它允许开发者在运行时构建查询,提供了更面向对象的查询方式。本篇将详细阐述Hibernate Criteria API的使用。 首先,Criteria API由...
创建Criteria查询的第一步是获取`Session`对象,然后调用`createCriteria()`方法,传入需要查询的实体类名。例如: ```java Criteria criteria = session.createCriteria(User.class); ``` 3. **添加限制条件...