C#.Net Castle ActiveRecord学习实践(7):使用HQL查询

摘要:虽然ActiveRecord为我们提供了Find()FindAll()这样两个静态的查询方法,并且有Where特性可供使用,但是仍然不能解决实际开发中一些复杂的查询,这时我们就需要通过HQL查询来实现。

 

主要内容

1HQL概述

2SimpleQuery查询

3ScalarQuery查询

4.自定义查询

5.使用CallBack

 

一.HQL简单介绍

HQL全名是Hibernate Query Language,它是一种完全面向对象的查询语言。先来看一下HQL最基本的一些用法

1From子句

from  Post

你也可以为Post起一个别名

from  Post  as  post

或者省略as

from  Post post

2Select 子句

select  Name,Author  from  Blog

也可以使用elements函数来查询一个集合

select  elements(blog.Posts)  from  Blog blog

3.使用聚合函数

HQL中也可以使用一些聚合函数

select   count ( * from  Blog blog

 

select   count (elements(blog.Posts))  from  Blog blog

HQL支持的聚合函数有

avg (),  sum (),  min (),  max (

count ( *

count (),  count ( distinct  ),  count ( all )

4Where子句

from  Blog blog  where  blog.Name  =  ‘Terry Lee’

 

from  Blog blog  where  blog.Name  is   not   null

详细可以参考http://www.hibernate.org/hib_docs/reference/en/html/queryhql.html

 

二.SimpleQuery查询

SimpleQuery是一种最简单的查询,它直接处理HQL语句,并返回一个集合,没有复杂的参数处理。具体用法可以参考下例:

[ActiveRecord( " Posts " )]

public   class  Post : ActiveRecordBase

{

    
// 

    
/// <summary>

    
/// 查询某一类别的所有Posts

    
/// </summary>

    
/// <param name="_strCategory">类别名称</param>

    
/// <returns></returns>


    
public static Post[] GetPostsByCategory(string _strCategory)

    
{

        SimpleQuery query 
= new SimpleQuery(

            
typeof(Post),

            
@"from Post post where post.Category = ?",

            _strCategory

            );

 

        
return (Post[])ExecuteQuery(query);

    }


    

    
/// <summary>

    
/// 查询某一时间段内发表的所有Posts

    
/// </summary>

    
/// <param name="start">开始时间</param>

    
/// <param name="end">结束时间</param>

    
/// <returns></returns>


    
public static int[] GetPostsInterval(DateTime start,DateTime end)

    
{

        SimpleQuery query 
= new SimpleQuery(

            
typeof(Post),typeof(int),

            
@"select post.Id from Post post where post.Created between ? and ?",

            start,end

            );

 

        
return (int[])ExecuteQuery(query);

    }


}


看一下简单的测试代码:

[Test]

public   void  TestGetPostsByCategory()

{

    
string StrCategory = "Castle";

    

    IList list 
= (IList)Post.GetPostsByCategory(StrCategory);

 

    
int expectedCount = 2;

 

    Assert.IsNotNull(list);

    Assert.AreEqual(expectedCount,list.Count);

}


 

[Test]

public   void  TestGetPostsInterval()

{

    DateTime start 
= Convert.ToDateTime("2006-01-01");

    DateTime end 
= DateTime.Now;

 

    IList list 
= (IList)Post.GetPostsInterval(start,end);

 

    
int expectedCount = 2;

 

    Assert.IsNotNull(list);

    Assert.AreEqual(expectedCount,list.Count);

}

 

三.ScalarQuery查询

ScalarQuery查询也是一种简单的直接处理HQL的查询,它也没有复杂的参数处理,只不过返回的值不是集合而是单一的值,具体用法参考下例:

[ActiveRecord( " Blogs " )]

public   class  Blog : ActiveRecordBase

{

    
// 

    
/// <summary>

    
/// 查询某作者发表的所有Posts数量

    
/// </summary>

    
/// <param name="_StrAuthor">作者姓名</param>

    
/// <returns></returns>


    
public static int GetPostNumByAuthor(string _StrAuthor)

    
{

        ScalarQuery query 
= new ScalarQuery(

            
typeof(Blog),

            
@"select count(elements(blog.Posts)) from Blog blog where blog.Author = ?",

            _StrAuthor

            );

 

        
return (int)ExecuteQuery(query);

    }


}


看一下简单的测试代码

[Test]

public   void  TestGetPostNumByAuthor()

{

    
string _StrAuthor = "Terry Lee";

 

    
int result = Blog.GetPostNumByAuthor(_StrAuthor);

 

    
int expectedCount = 2;

 

    Assert.AreEqual(expectedCount,result);

}


四.自定义查询

在实际开发中,我们所面对的查询远不止上面所说得这么简单,有时候我们需要处理一些自定义的参数,或者执行自定义的查询语句,这时需要我们编写自定义的ActiveRecord查询,首先要添加一个类,让它继承于基类ActiveRecordBaseQuery,并覆写Execute()方法(或者实现IactiveRecordQuery接口),如下例所示

public   class  QueryWithNamedParameters : ActiveRecordBaseQuery

{

    
private string _authorName = null;

    
private int _maxResults = 2;

    

    
public QueryWithNamedParameters()

        : 
base(typeof(Blog)) 

    
{

 

    }


    

    
public string AuthorName

    
{

        
get return _authorName; }

        
set { _authorName = value; }

    }


    

    
public int MaxResults

    
{

        
get return _maxResults; }

        
set { _maxResults = value; }

    }


 

    
public override object Execute(ISession session)

    
{

        String hql 
= "from Blog blog";

 

        
if (_authorName != null)

            hql 
+= " where blog.Author = :author";

 

        IQuery q 
= session.CreateQuery(hql);

 

        
if (_authorName != null)

            q.SetString(
"author", _authorName);

 

        q.SetMaxResults(_maxResults);

 

        
return base.GetResultsArray(typeof(Blog), q.List(), nullfalse);

    }


}


使用我们自定义的类

/// <summary>

/// 自定义查询

/// </summary>

/// <param name="authorName"></param>

/// <returns></returns>


public   static  Blog[] GetThreeBlogsFromAuthor(  string  authorName )

{

    QueryWithNamedParameters q 
= new QueryWithNamedParameters();

    q.AuthorName 
= authorName;

    q.MaxResults 
= 3;

    
return (Blog[]) ExecuteQuery(q);

}


看一下简单的测试代码

[Test]

public   void  TestCustomQuery()

{

    
string _StrAuthor = "Terry Lee";

 

    IList list 
= Blog.GetThreeBlogsFromAuthor(_StrAuthor);

 

    
int expectedCount = 3;

 

    Assert.IsNotNull(list);

    Assert.AreEqual(expectedCount,list.Count);

}

 

五.使用CallBack

还有一种实现方式是使用Execute()方法,这种方式与我们前面所讲的自定义查询是差不多的,只不过不用增加额外的自定义类。

[ActiveRecord( " Blogs " )]

public   class  Blog : ActiveRecordBase

{

    
//

    
/// <summary>

    
/// 通过CallBack执行

    
/// </summary>

    
/// <param name="author"></param>

    
/// <returns></returns>


    
public static Blog[] GetPostsFromAuthor( string author )

    
{

        
return (Blog[]) Execute( typeof(Blog), new NHibernateDelegate(GetPostsFromAuthorCallback), author);

    }


 

    
private static object GetPostsFromAuthorCallback(ISession session, object instance )

    
{

        
// 创建查询

        IQuery query 
= session.CreateQuery( "from Blog blog where blog.Author = :author" );

 

        
// 设置参数

        query.SetString(
"author", (string) instance);

 

        
// 获取结果

        IList results 
= query.List();

 

        
// 转化结果为Array

        Blog[] blogs 
= new Blog[results.Count];

        results.CopyTo(blogs, 
0);

 

        
// 返回结果

        
return blogs;

    }


}

 

编写测试代码

[Test]

public   void  TestGetPostsFromAuthor()

{

    
string _StrAuthor = "Terry Lee";

 

    IList list 
= Blog.GetPostsFromAuthor(_StrAuthor);

 

    
int expectedCount = 4;

 

    Assert.IsNotNull(list);

    Assert.AreEqual(expectedCount,list.Count);

}

 

关于使用HQL查询就介绍到这儿了,相信通过HQL查询可以解决我们开发中的绝大多数的复杂查询问题。

 

 

参考资料

文中主要内容来自于Castle的官方网站http://www.castleproject.org

作者: TerryLee
出处: http://terrylee.cnblogs.com
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值