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

主要内容

1.HQL概述

2.SimpleQuery查询

3.ScalarQuery查询

4.自定义查询

5.使用CallBack

一.HQL简单介绍

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

1.From子句

from Post

你也可以为Post起一个别名

from Post as post

或者省略as

from Post post

2.Select 子句

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)

4.Where子句

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(), null, false);

    }

}

使用我们自定义的类

/**//// <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

Castle ActiveRecord学习实践(7):使用HQL查询相关推荐

  1. Castle ActiveRecord学习实践(8)HQL查询

    本篇来了解下Castle ActiveRecord hql 查询语句. 博客园中讲解Castle ActiveRecord 的文章已经很多了,博主就不自己写了.转载一篇TerryLee大大的文章. 摘 ...

  2. Castle ActiveRecord学习实践(1):快速入门指南

    摘要:最近几天有时间看了一下Castle,原来它的功能是如此的强大,从数据访问框架到IOC容器,再到WEB框架,基本包括了整个开发过程中的所有东西,看来得好好学习研究一下了,并且打算把自己学习过程的一 ...

  3. Castle ActiveRecord学习实践(6):延迟加载和使用Where子句

    摘要:在ActiveRecord中把数据库表之间的关联关系采用对象间的聚合关系来表现,然而这却带来一系列的性能上的问题.就像我在One-Many中用到的例子Blog,使用Blog.Find(1)查找了 ...

  4. Castle ActiveRecord学习实践(2):构建配置信息

    摘要:ActiveRecord在底层封装了NHibernate,在框架启动时需要指定相关的配置信息,那么我们需要配置些什么?又该如何去配置呢?本文将会介绍在ActiveRecord中构建配置信息. 主 ...

  5. Castle ActiveRecord学习实践(5):实现Many–Many关系的映射

    摘要:多对多的关系在日常开发中也会经常遇到,在ActiveRecord中我们用HasAndBelongsToMany特性来实现Many-Many的关联,本文将通过一个具体的实例来介绍这一用法. 主要内 ...

  6. Castle ActiveRecord学习实践(4):实现One-Many关系的映射

    摘要:前面几篇文章简单的介绍了ActiveRecord中的基本映射以及构建配置信息,本文我们用ActiveRecord里面的Blog,Post例子来实现One-Many/Many-One关联. 主要内 ...

  7. Castle ActiveRecord学习笔记四:各种映射

    这里主要来说明ActiveRecord的属性与数据库及其字段的对应关系. 主要以ActiveRecordAttribute.PrimaryKeyAttribute.PropertyAttribute来 ...

  8. Castle ActiveRecord学习(四)延迟加载、分页查询、where条件

    一.延迟加载 //用户发布的主题,一对多:Table:外键表:ColumnKey:外键:Lazy:延迟加载:Cascade:级联操作(级联删除)[HasMany(typeof(ThemeInfo), ...

  9. castle activerecord mysql_Castle ActiveRecord配置中需要注意的地方

    关于Castle 的开发可参考李会军老师的Castle 开发系列文章,里面有关于ActiveRecord学习实践系列和Castle IOC容器系列两个部分,是比较好的教程. 这里主要说明在Castle ...

最新文章

  1. Android应用程序进程启动过程的源代码分析(1)
  2. 文曲星猜数游戏,无测试代码
  3. JavaWeb:JDBC之数据库连接池
  4. AspectJ注解版和XML版
  5. 我们都在深夜,参差不齐地入眠
  6. 关于利用border-radius变形后,margin的参照对象
  7. IPHONE手机知识大全(下)
  8. 电脑如何让两个文件夹同步更新备份?
  9. 面试题整理|45个CSS面试题
  10. Windows Server 2008 R2 下载地址
  11. 一条挨踢老狗的2017年终总结
  12. php的命名空间和自动加载实现
  13. element-plus 中loading 自定义图片
  14. ubuntu安装vbox虚拟机
  15. 将MATLAB任务栏变成白色的图标恢复
  16. python求列表list平均值的方法
  17. ASP .NET MVC项目研发总结
  18. Centos 基本命令
  19. Dubbo进阶(二):Dubbo是什么
  20. C++虐我千百遍 我愿待她如初恋

热门文章

  1. windows系统远程桌面相关内容
  2. iphone远程连接mysql_如何远程连接数据库 原来是这样的
  3. 无线通信信道的衰落特性(大尺度衰落和小尺度衰落)
  4. 51单片机定时器初值的计算
  5. KubeSphere对于已经部署的服务进行修改后重新进行部署
  6. Eclipse“ctrl+左键”链到实现类
  7. java 重载赋值_java中构造方法,set/get方法,方法重载使用解读
  8. base6 python 字节_Python使用base64模块进行二进制数据编码详解
  9. 解决MYSQL不报错误详细信息的问题 Can‘t find error-message file
  10. springboot项目启动成功后执行一段代码的两种方式