http://www.cnblogs.com/abluedog/archive/2006/04/26/385978.html
可能很多人象我一样,刚开始接触 HQL 时,脑袋一片混沌,这是什么语法嘛!!之所以这样,是因为我们总是会先入为主地将之与 SQL 想比,虽然 HQL 看起来很 SQL ,而且设计时就有这样的意图,但是毕竟是两种差别很大的东西,难免就会出现理解偏差的问题。好了,我们今天就不让大家脑袋发晕了, HQL 我们暂时放一放。今天我们来说另外一种查询方法:
Criteria Query.
什么是 Criteria Query? 简单说,就是将我们的查询条件封装为一个预定义的查询对象,由这个查询对象来执行查询,而不用我们再去写 HQL 了,而且更接近我们贯常的编程习惯。
是不是很不错?让我们来 look look :
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
注意这一句:
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
Eq 是 Equal 的缩写,意思是添加一个查询表达式, Person.Name = “Jackie Chan”
对应 HQL 就是:
from Person p where p.Name=”Jackie Chan”
NHibernate 会在运行时动态生成类似上面的 HQL ,我们可以在配置文件把 show-sql 打开,观看生成的 SQL 。
这样是不是感觉清晰多了?又回到我们以前的编码习惯了!
为了对应 HQL 的种种查询条件, NHibernate 预定义了大量的 Expression 方法,我们列几个如下:
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
基本上对应了大部分
下面,我们详细介绍 Criteria 的用法。
1. Example 查询
我们常常有这样的查询页面:
用户可以输入“姓名”、“性别”、“年龄”等等来进行查询,而我们常常的做法就是如下的烦琐:
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
代码看起来实在是不甚美观,有什么解决办法呢?
Criteria 提供了专为这种问题而设计的 Example 查询,如下:
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
请注意:
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
这句代码的意思是通过构造的 person 对象的属性来生成表达式,实际生成的代码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
对应上面的问题,我们简单地 new 出一个 person 对象,然后填充其属性即可,不用再去构造那丑陋的条件判断语句了!
2. 排序
我们想对返回的 list 进行排序,该怎么办呢?如下:
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
请注意:
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
这句代码的意思是在 criteria 上构造一个排序对象,并以 Age 属性做正序排列, NHibernate 在运行时会生成如下语句:
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
如你所猜想, Order 类肯定有另外一个“ Desc “方法:)
3. 限制记录范围
在显示大量的记录时,我们常常采用的方法就是分页,如果用 NHibernate 来做,该怎么办呢?
如下代码:
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
这样,我们就达到了分页的目的。
注意:
NHibernate 的分页机制实际上依赖于不同的数据库实现,所以,对特定的某种数据库,并不一定是效率最好的,比如对 SQLServer (为什么受伤的总是俺?为什么总是说俺比不上 Oracle ?俺都赶在 2005 年年底出 2005 版本了!!)。想知道为什么吗?很简单, check 一下上面代码生成的 SQL 就清楚了!或者深入点再看看 NHibernate 的分页代码,我就不解释了,自己动手,丰衣足食:)
总体来讲, Criteria 对我们来说更熟悉,更容易上手,但是目前 Criteria 还是不够完善——将对应的 HQL 一一封装实在太烦琐了,所以 NHibernate 还是以 HQL 查询为主,我们在使用的时候则看需要了,要么使用 HQL ,要么 HQL 和 Criteria 混合使用,重要的是解决问题,对不?