ActiveRecord学习(四):HQL应用

    前面介绍了如何使用配置AR,一些简单的操作以及常见几种映射关系的实现,今天我们就来讲一下HQL,前段时间我在博客园上看有人介绍NHibernate的时候说"HQL是NHibernate中最激动人心的部分",这话确实不错,它同样也是AR中最激动人心的部分(个人感觉),HQL看起来很像SQL语句,但实质完全不一样,它是一种完全的面向对象的查询语言,全称Hibernate Query Language,通过HQL我们可以实现一些比较复杂的查询.
    那么什么才能称之为HQL语句呢?如下:

From Company

   这就是一个HQL语句,它相当于这样的SQL语句:Select * Form Company,即查询所有的单位信息.HQL也可以想SQL里那样使用别名,使用聚合函数等等.它支持的聚合函数如下:
1.求平均值:avg()
2.求和:sum()
3.最大值和最小值:max(),min()
4.求记录数:count()
等等......
值得注意的是:HQL语句是区分大小写的,因为它查询面向的是对象,而我们定义对象的C#语言是区分大小写的。
更详细的关于HQL的资料请参考:http://www.hibernate.org/hib_docs/reference/en/html/queryhql.html
   下面来说一下ActiveRecord里提供的几种查询方式:
1、SimpleQuery和ScalarQuery
  二者都是直接处理HQL语句的简单查询,没有复杂的参数处理,区别是:SimpleQuery返回值是一个集合,而ScalarQuery返回的是单一值,具体用法祥见下面的代码:
SimpleQuery:
//HQL的用法,和NHibernate中差不多,但在返回值的处理上比NHibernate中做的好
        public static Company[] FindByName(string cname)
        
{
            
//注意:Hql中大小写区分
            string hql = @"from Company c where c.Cname=?";
            SimpleQuery sq 
= new SimpleQuery(typeof(Company),hql,cname);

            
return (Company[])ExecuteQuery(sq);
            
        }
ScalarQuery:
//得到单位个数
        public static int GetCompanyNumber()
        
{
            
string hql = @"select count(*) from Company";

            ScalarQuery sq 
= new ScalarQuery(typeof(Company),hql,null);

            
return (int)ExecuteQuery(sq);
        }

2、Custom Query(自定义查询)
 使用这种查询首先要添加对NHibernate和Nullables这两个程序集的引用。然后我们要为我们所使用的查询定义一个参数类,这个类必须继承ActiveRecordBaseQuery类并且要override Execute方法(或实现IActiveRecordQuery接口也可)。使用方法如下,以查询某个类别的单位为例,首先定义参数类:
using System;
using Castle.ActiveRecord;
using Castle.ActiveRecord.Queries;
using NHibernate;

namespace AR.Model
{
    
/// <summary>
    
/// CompanyCustomQuery 的摘要说明。
    
/// </summary>

    public class CompanyCustomQuery : ActiveRecordBaseQuery
    
{
        
public CompanyCustomQuery() : base(typeof(Company))
        
{
            
        }


        
private string _type = string.Empty;
        
//指定返回最大记录数
        private int maxResultLen = 10;


        
public string Type
        
{
            
get{return _type;}
            
set{_type = value;}
        }


        
public override object Execute(NHibernate.ISession session)
        
{
            
string hql = "from Company c";

            
if(_type != string.Empty)
            
{
                hql 
+= " where c.Type= :type";
            }


            IQuery query 
= session.CreateQuery(hql);

            
if(_type != string.Empty)
            
{
                query.SetString(
"type",Type);
            }


            query.SetMaxResults(maxResultLen);

            
return base.GetResultsArray(typeof(Company),query.List(),null,false);
        }


    }

}
调用方法如下:
public static Company[] GetCompanyListByType(string type)
        
{
            CompanyCustomQuery ccq 
= new CompanyCustomQuery();
            ccq.Type 
= type;
            
            
return (Company[])ExecuteQuery(ccq);
        }


3.Execute CallBack

 这种查询方式和CustomQuery差不多,只不过不需要再添加一个参数类了.使用方法如下:

public static Company[] GetCompanyListByType(string type)
        
{
            
return (Company[])Execute(typeof(Company),new NHibernateDelegate(GetCompanyListCallBack),type);
        }


        
public static object GetCompanyListCallBack(ISession session,object instance)
        
{
            
//create the query
            IQuery query = session.CreateQuery(@"from Company c Where c.Type=:type");
            
//set parameters
            query.SetString("type",instance.ToString());
            
            IList list 
= query.List();

            Company[] companies 
= new Company[list.Count];
            list.CopyTo(companies,
0);

            
return companies;



        }

以上代码在VS2003中调试通过.
关于ActiveRecord的HQL就说这么多.以上资料参考:http://www.castleproject.org/index.php/ActiveRecord:Using_HQL
希望能与园子里的朋友多多交流.
Email:pwei013@163.com

posted on 2006-05-22 22:38 Daniel Pang 阅读(2086) 评论(5)  编辑 收藏 所属分类: Castle

评论

#1楼  2006-05-23 09:13 天好蓝-崇崇      


有一点点问题,我更正一下:

"或实现IActiveRecordBaseQuery接口也可" 这句话不是很正确
应该是实现IActiveRecordQuery 接口

IActiveRecordQuery 接口,成员如下:
object Execute(
ISession session
);

或是继承ActiveRecordBaseQuery抽象类,重写其抽象方法
抽象方法:
public abstract object Execute(
ISession session
);

  回复  引用  查看    

#2楼 [楼主] 2006-05-23 09:33 SHY520      

@天好蓝-崇崇
不好意思,我写错了,现已经更正   回复  引用  查看    

#3楼  2006-05-23 10:24 Terrylee      

@SHY520
这几篇我都看了一下,写的很详细:-)

我当时写的那些文章不可能把所有的都写完整,希望楼主能够研究补充一些,呵呵   回复  引用  查看    

#4楼 [楼主] 2006-05-23 10:48 SHY520      

@Terrylee
我也刚开始研究了一下,主要你你写的比较好,所以我现在对AR也很感兴趣,刚好因为工作关系,后面要做个权限管理的组件,我可能会用AR来尝试一下.
还有你的MSN是多少?方便以后交流,呵呵   回复  引用  查看    

#5楼  2006-05-23 11:33 Terrylee      

@SHY520
MSN在我的Blog上面有:-)   回复  引用  查看    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  博客园首页

  新闻频道

  社区

  小组

  博问

  网摘

  闪存

  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2006-05-27 11:44 编辑过
成果网帮您增加网站收入


相关链接:
 


<2006年5月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

导航

统计

公告

技术交流平台,真诚的希望能和园子里的朋友交流技术,共同进步!
欢迎加入Castle+IBatisNet交流群:2923364(已满),37745404
特别提示:本站文章若无特别申明,均为原创,转载请注明出自'博客园'!
Emailpwei013#163.com
MSNshypw520#gmail.com

与我联系

搜索

 

常用链接

留言簿(10)

我参与的团队

随笔分类(98)

随笔档案(74)

相册

收藏夹(19)

MY BLOG

公司主页

情侣BLOG

友情链接

积分与排名

最新随笔

最新评论

阅读排行榜

评论排行榜