NHibernate Step by Step (五)Criteria Query

NHibernate Step by Step (五)Criteria Query
可能很多人象我一样,刚开始接触HQL时,脑袋一片混沌,这是什么语法嘛!!之所以这样,是因为我们总是会先入为主地将之与SQL想比,虽然HQL看起来很SQL,而且设计时就有这样的意图,但是毕竟是两种差别很大的东西,难免就会出现理解偏差的问题。好了,我们今天就不让大家脑袋发晕了,HQL我们暂时放一放。今天我们来说另外一种查询方法:
Criteria Query.
什么是Criteria Query?简单说,就是将我们的查询条件封装为一个预定义的查询对象,由这个查询对象来执行查询,而不用我们再去写HQL了,而且更接近我们贯常的编程习惯。
是不是很不错?让我们来look look:

 
// 创建关联到某个类的查询对象
ICriteria criteria  =  session.CreateCriteria( typeof (Person));

// 添加表达式
criteria.Add(Expression.Eq( " Name " , " Jackie Chan " ));

IList list 
=  criteria.List();
 
注意这一句:
  
Expression.Eq( " Name " , " Jackie Chan " )
Eq是Equal的缩写,意思是添加一个查询表达式,Person.Name = “Jackie Chan”
对应HQL就是:
from Person p where p.Name=”Jackie Chan”
NHibernate会在运行时动态生成类似上面的HQL,我们可以在配置文件把show-sql打开,观看生成的SQL。
这样是不是感觉清晰多了?又回到我们以前的编码习惯了!
 
为了对应HQL的种种查询条件,NHibernate预定义了大量的Expression方法,我们列几个如下:

HQL的语义,详细的说明请参考api。

 
Eq           =  Equal
Gt          
=  Greater than
Lt          
=  Less than
Like        
=  Like
Not         
=  Not
IsNull      
=  Is Null

基本上对应了大部分
 
下面,我们详细介绍Criteria的用法。
1. Example查询
我们常常有这样的查询页面:
用户可以输入“姓名”、“性别”、“年龄”等等来进行查询,而我们常常的做法就是如下的烦琐:
string  condition  =  “”;
if (txtName.Text  !=  null )
        condition 
+=  “ Name = ”  +  txtName.Text;

if (txtSex.Text  !=  null )
       condition 
+=  “ and Sex = ”  +  txtSex.Text;

……


代码看起来实在是不甚美观,有什么解决办法呢?
Criteria提供了专为这种问题而设计的Example查询,如下:

ICriteria criteria  =  session.CreateCriteria( typeof (Person));

Person person 
=  new  Person();
person.Name 
=  " Jackie Chan " ;
person.Age 
=  50 ;

// 创建一个Example对象
criteria.Add(Example.Create(person));
IList list 
=  criteria.List();
 
请注意:
  
criteria.Add(Example.Create(person));
这句代码的意思是通过构造的person对象的属性来生成表达式,实际生成的代码如下:
  
SELECT  this.id  as  id0_, this.name  as  name0_, this.age  as  age0_  FROM  Person this  WHERE  (this.age  =  @p0 )
对应上面的问题,我们简单地new出一个person对象,然后填充其属性即可,不用再去构造那丑陋的条件判断语句了!
 
2. 排序
我们想对返回的list进行排序,该怎么办呢?如下:
ICriteria criteria  =  session.CreateCriteria( typeof (Person));
criteria.Add(Expression.Gt(
" Age " 20 )); 

// 添加一个排序对象
criteria.AddOrder(Order.Asc( " Age " ));

IList list 
=  criteria.List();

 
请注意:
  
criteria.AddOrder(Order.Asc( " Age " ));
这句代码的意思是在criteria上构造一个排序对象,并以Age属性做正序排列,NHibernate在运行时会生成如下语句:
  
SELECT  this.id  as  id0_, this.name  as  name0_, this.age  as  age0_  FROM  Person this  WHERE  this.age  >  @p0  ORDER  BY  this.age  asc
如你所猜想,Order类肯定有另外一个“Desc“方法:)
 
3. 限制记录范围
在显示大量的记录时,我们常常采用的方法就是分页,如果用NHibernate来做,该怎么办呢?
如下代码:
ICriteria criteria  =  session.CreateCriteria( typeof (Person));

// 从第10条记录开始取
criteria.SetFirstResult( 10 );

// 取20条记录
criteria.SetMaxResults( 20 );

IList list 
=  criteria.List();
 
这样,我们就达到了分页的目的。
注意:
NHibernate的分页机制实际上依赖于不同的数据库实现,所以,对特定的某种数据库,并不一定是效率最好的,比如对SQLServer(为什么受伤的总是俺?为什么总是说俺比不上Oracle?俺都赶在2005年年底出2005版本了!!)。想知道为什么吗?很简单,check一下上面代码生成的SQL就清楚了!或者深入点再看看NHibernate的分页代码,我就不解释了,自己动手,丰衣足食:)
 
 
总体来讲,Criteria对我们来说更熟悉,更容易上手,但是目前Criteria还是不够完善——将对应的HQL一一封装实在太烦琐了,所以NHibernate还是以HQL查询为主,我们在使用的时候则看需要了,要么使用HQL,要么HQL和Criteria混合使用,重要的是解决问题,对不?

好了,这一篇就讲这么多,我们下次再接着练习。
任何建议或者批评,请e: abluedog@163.com
 
 
posted on 2006-04-26 21:24 abluedog 阅读(3347) 评论(16)   编辑   收藏 所属分类: NHibernate
<script type=text/javascript> // </script>
评论
#2楼  2006-04-27 09:50 菜鸟成长日记
Very Good 学习!    回复   引用   查看    
#3楼  2006-04-27 10:40 发芽的豆子
很好 。。。。    回复   引用   查看    
#4楼 [未注册] 2006-04-27 13:31 pwei
NHibernate中怎么使用存储过程?    回复   引用   查看    
#5楼 [未注册] 2006-04-27 17:04 pwei
我用Criteria的Example查询查不到结果,怎么回事?

[TestMethod]
public void CriteriaExample()
{
Person per = new Person();
per.Id = 4;
ICriteria criteria = session.CreateCriteria(typeof(Person));
criteria.Add(Example.Create(per));

IList list = criteria.List();

Assert.AreNotEqual(0,list.Count, "fail");
}

请问哪写错了?    回复   引用   查看    
#6楼 [未注册] 2006-04-27 17:05 pwei
另外,很期待你的下一篇文章,能不能快点,大哥?    回复   引用   查看    
#7楼 [楼主] 2006-04-27 20:47 abluedog
@pwei
Example.create:Version properties, identifiers and associations are ignored. By default, null valued properties are excluded.    回复   引用   查看    
#8楼 [未注册] 2006-04-28 09:39 pwei
@abluedog
是不是我上面写的方法转换成HQL之后并不只是ID这一个参数?
如果是的话,怎么样才能达到我想要的效果呢?    回复   引用   查看    
#9楼 [未注册] 2006-04-28 09:44 pwei
现在NHibernate的最新版本号是多少?
我的是在你第一篇文章中的地址下载的    回复   引用   查看    
#10楼 [未注册] 2006-05-12 16:42 mzl
1.0.2吧.    回复   引用   查看    
#11楼  2006-06-07 18:10 家中慢步
abluedog,老兄,繼續啊,怎麽四月之後就沒有下文了?期待你的spring.net系列    回复   引用   查看    
#12楼  2006-11-26 17:50 IT猎人
在试了楼主的示例后,发现几处不对的地方:
1.SELECT this.id as id0_, this.name as name0_, this.age as age0_ FROM Person this WHERE (this.age = @p0)应该是
SELECT this.id as id0_, this.age as age0_, this.name as name0_ FROM Person this WHERE (this.age = @p0 and this.name = @p1)
2.//从第10条记录开始取
criteria.SetFirstResult(10);
这里不应该是说从第10条开始,而就是第11条,
criteria.SetFirstResult(9);才是第10条.NHibernate中是从0开始计数的.
   回复   引用   查看    
#13楼 [未注册] 2006-12-30 14:58 bondy
谁有code smith啊,谢谢发一个给我 bondy916@163.ocm
不胜感激....    回复   引用   查看    
#14楼 [未注册] 2007-06-15 16:47 任国强
能不能问一下,你的Order 还有Example在那个命名空间下啊    回复   引用   查看    
#15楼 [未注册][TrackBack] 2007-07-15 13:53 大冰
NHibernateStepbyStep(五)CriteriaQuery NHibernateStepbyStep(五)CriteriaQuery 可能很多人象我一样,刚开始...
[引用提示]大冰引用了该文章, 地址: http://www.cnblogs.com/hanbing768/archive/2007/07/15/818697.html    回复   引用   查看    
#16楼 [未注册][TrackBack] 2007-07-24 17:27 MichaeL
NHibernateStepbyStep(五)CriteriaQuery 转载地址:http://www.cnblogs.com/abluedog/archive/2006/04/26/3...
[引用提示]MichaeL引用了该文章, 地址: http://www.cnblogs.com/MichaelLu/archive/2007/07/24/829714.html    回复   引用   查看    
#1楼 [未注册] 2006-04-27 09:10 iokala
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值