第 16 章 条件查询(Criteria Queries)
具有一个直观的、可扩展的条件查询API是Hibernate的特色。
16.1. 创建一个Criteria 实例
org.hibernate.Criteria接口表示特定持久类的一个查询。Session是 Criteria实例的工厂。
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->Criteria crit = sess.createCriteria(Cat.class);
crit.setMaxResults(50);
List cats = crit.list();
16.2. 限制结果集内容
一个单独的查询条件是org.hibernate.criterion.Criterion 接口的一个实例。org.hibernate.criterion.Restrictions类 定义了获得某些内置Criterion类型的工厂方法。
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "Fritz%") )
.add( Restrictions.between("weight", minWeight, maxWeight) )
.list();
约束可以按逻辑分组。
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "Fritz%") )
.add( Restrictions.or(
Restrictions.eq( "age", new Integer(0) ),
Restrictions.isNull("age")
) )
.list();
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->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。
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->List cats = sess.createCriteria(Cat.class)
.add( Restrictions.sql("lower({alias}.name) like lower(?)", "Fritz%", Hibernate.STRING) )
.list();
{alias}占位符应当被替换为被查询实体的列别名。
Property实例是获得一个条件的另外一种途径。你可以通过调用Property.forName() 创建一个Property。
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->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();
16.3. 结果集排序
你可以使用org.hibernate.criterion.Order来为查询结果排序。
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "F%")
.addOrder( Order.asc("name") )
.addOrder( Order.desc("age") )
.setMaxResults(50)
.list();
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->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();
16.4. 关联
你可以使用createCriteria()非常容易的在互相关联的实体间建立 约束。
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "F%")
.createCriteria("kittens")
.add( Restrictions.like("name", "F%")
.list();
注意第二个 createCriteria()返回一个新的 Criteria实例,该实例引用kittens 集合中的元素。
接下来,替换形态在某些情况下也是很有用的。
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->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()。
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->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");
}
16.5. 动态关联抓取
你可以使用setFetchMode()在运行时定义动态关联抓取的语义。
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "Fritz%") )
.setFetchMode("mate", FetchMode.EAGER)
.setFetchMode("kittens", FetchMode.EAGER)
.list();
这个查询可以通过外连接抓取mate和kittens。 查看第 20.1 节 “ 抓取策略(Fetching strategies) ”可以获得更多信息。
16.6. 查询示例
org.hibernate.criterion.Example类允许你通过一个给定实例 构建一个条件查询。
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->Cat cat = new Cat();
cat.setSex('F');
cat.setColor(Color.BLACK);
List results = session.createCriteria(Cat.class)
.add( Example.create(cat) )
.list();
版本属性、标识符和关联被忽略。默认情况下值为null的属性将被排除。
你可以自行调整Example使之更实用。
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->Example example = Example.create(cat)
.excludeZeroes() //exclude zero valued properties
.excludeProperty("color") //exclude the property named "color"
.ignoreCase() //perform case insensitive string comparisons
.enableLike(); //use like for string comparisons
List results = session.createCriteria(Cat.class)
.add(example)
.list();
你甚至可以使用examples在关联对象上放置条件。
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->List results = session.createCriteria(Cat.class)
.add( Example.create(cat) )
.createCriteria("mate")
.add( Example.create( cat.getMate() ) )
.list();
16.7. 投影(Projections)、聚合(aggregation)和分组(grouping)
org.hibernate.criterion.Projections是 Projection 的实例工厂。我们通过调用 setProjection()应用投影到一个查询。
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->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子句中。
你可以选择把一个别名指派给一个投影,这样可以使投影值被约束或排序所引用。下面是两种不同的实现方式:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->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实例中。简而言之,当你添加一个投影到一个投影列表中时 你可以为它指定一个别名:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->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()来表示投影:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->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();
16.8. 离线(detached)查询和子查询
DetachedCriteria类使你在一个session范围之外创建一个查询,并且可以使用任意的 Session来执行它。
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
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获得。
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->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();
甚至相互关联的子查询也是有可能的:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->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();
分享到:
相关推荐
在Hibernate中,使用`Criteria`进行查询时,可以通过添加排序条件来对结果集进行排序。`Criteria`提供了一个非常灵活的方式来实现这一点。 **示例代码**: ```java Criteria criteria = session.createCriteria...
Criteria API是Hibernate提供的另一种查询方式,它提供了更加面向对象的API,可以动态构建查询条件。下面是一个使用Criteria API的例子: ```java Session session = sessionFactory.openSession(); Criteria ...
本实践项目结合了这两个框架,实现了基于Struts的前端展示和基于Hibernate的数据访问层,提供了分页和条件查询功能,这对于大型Web应用来说是非常基础且重要的。 **Struts框架** 是一个用于构建企业级Web应用程序的...
Hibernate还提供了Criteria API,它是更加面向对象的查询方式。使用Criteria API查询部分字段,你可以这样做: ```java Criteria criteria = session.createCriteria(EntityName.class); criteria.add...
HQL支持各种条件查询,如等于、不等于、大于、小于等操作符: ```java query = session.createQuery("from Customer c where c.name = 'John'"); customers = query.list(); ``` 上述代码将返回所有名为'John'的...
- Criteria Queries与Detached Criteria:Criteria Queries允许在运行时构建查询,而Detached Criteria则允许在不与数据库连接的情况下预定义查询,稍后进行执行,提高了灵活性。 4. Hibernate缓存机制: ...
Criteria Queries 是 Hibernate 的一种查询方式,可以使用面向对象的方式来查询对象。Criteria Queries 可以使用专门的 API 操作,例如 add、list 等。 Native SQL Hibernate 支持 native SQL 操作,可以使用原生 ...
数据库迁移(Migration)和遗留模型引导(Legacy Bootstrapping)、迁移(Migration)、域模型(Legacy Domain Model)、Hibernate Criteria查询(Legacy Hibernate Criteria Queries)、Hibernate原生查询(Legacy ...
29. 旧版Hibernate Criteria查询(Legacy Hibernate Criteria Queries):这部分讲述了如何处理旧版的Criteria查询。 30. 旧版Hibernate原生查询(Legacy Hibernate Native Queries):手册中说明了如何处理旧版的原生...
5. **使用预编译的SQL(Hibernate Named Queries)**: 提高查询效率,减少SQL注入风险。 通过深入理解和熟练运用Hibernate查询机制,可以大大提高Java应用程序的数据库操作效率和代码可维护性。无论是HQL还是...
除了HQL外,Hibernate还提供了Criteria API,这是一种更加面向对象的查询方式,可以动态构建查询条件。Criteria API提供了更丰富的查询选项,如 Restrictions、Projections 和 Order 等,使得代码更具灵活性。 总结...
15. 条件查询(Criteria Queries); 16. Native SQL查询; 17. 过滤数据; 18. XML映射; 19. 提升性能; 20. 工具箱指南; 21. 示例:父子关系(Parent Child Relationships); 22. 示例:Weblog 应用程序; 23. 示例:复杂...
在Hibernate中,核心概念包括实体(Entities)、持久化类(Persistent Classes)、会话(Sessions)、事务(Transactions)和查询(Queries)。实体是应用程序中的业务对象,它们对应数据库中的表;持久化类是包含@...
在Hibernate中,核心概念包括实体(Entities)、会话(Sessions)、事务(Transactions)、查询(Queries)等。首先,实体是业务逻辑中的对象,它们通过注解或者XML配置与数据库表对应。例如,一个名为`User`的实体...
当HQL或Criteria API无法满足特定需求时,Hibernate允许直接执行原生SQL查询,通过SQLQuery对象处理结果。 10. 性能优化: Hibernate提供了缓存机制,如一级缓存(Session级)和二级缓存(SessionFactory级),...
Hibernate设计之初就鼓励使用HQL或Criteria API进行查询和更新,以保持代码的可读性和可维护性。 三、HQL更新查询的使用 1. 基本语法:HQL更新查询的语法结构类似于SQL的UPDATE语句,但以"UPDATE"关键字开头,后跟...
10.4.3. 条件查询(Criteria queries) 10.4.4. 使用原生SQL的查询 10.5. 修改持久对象 10.6. 修改脱管(Detached)对象 10.7. 自动状态检测 10.8. 删除持久对象 10.9. 在两个不同数据库间复制对象 10.10. ...
10.4.3. 条件查询(Criteria queries) 10.4.4. 使用原生SQL的查询 10.5. 修改持久对象 10.6. 修改脱管(Detached)对象 10.7. 自动状态检测 10.8. 删除持久对象 10.9. 在两个不同数据库间复制对象 10.10. ...
10.4.3. 条件查询(Criteria queries) 10.4.4. 使用原生SQL的查询 10.5. 修改持久对象 10.6. 修改脱管(Detached)对象 10.7. 自动状态检测 10.8. 删除持久对象 10.9. 在两个不同数据库间复制对象 10.10. ...
JPA 2.0带来了更多的查询选项,包括 Criteria API 和 Named Queries,这些都增强了对数据查询的灵活性。 其次,4.1版本在事务管理和缓存方面也有所增强。它支持JTA(Java Transaction API)和JPA的...