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  阅读(3200)  评论(5编辑  收藏  举报

导航