在ActiveRecord中实现稍微复杂的一点的查询,我们就不能用使用Find(id),FindAll()这两个静态的方法了,这时就需要使用HQL语句来实现,在平常使用Castle的时候我想大家都注意到在ActiveRecordBase类下,由于只提供了Find(id),FindAll()这样两个静态的查询方法,这两个方法在我们查询中还远远不够,仍然不能解决实际开发中一些复杂的查询,这方面ActiveRecord为我们提供了HQL语言的支持。
一.HQL语句介绍
HQL全名是Hibernate Query Language,它是一种完全面向对象的查询语言。我门先来看一下HQL最基本的一些用法(类似SQL):
From子句-------->如:From Name,也可取别名,如:From Name as name,也可省略as,如:From Name name.
Select子句----->如:Select Name from TableName.
Where子句--->如:From TableName as tn where tn.Name is not null.
使用聚合函数-->如:Select * From Table as t.
......
更多HQL用法请参考相关资料,这里不作详细介绍。
二.使用示例
要使用HQL语句来进行一系列的查询前需先引用:Castle.ActiveRecord.Queries;在Queries类下封装有HqlBaseQuery以及派生于他的CountQueryScalarQuery,SimpleQuery类。
示例代码:用户类(Users)和新闻类(News)
1
[ActiveRecord("Users")]
2
public class Users:ActiveRecordBase
3

{
4
成员#region 成员
5
private int _oid;
6
[PrimaryKey(PrimaryKeyType.Identity,"User_Oid")]
7
public int Oid
8
{
9
get
{ return _oid; }
10
set
{ _oid = value; }
11
}
12
private string _userName;
13
[Property("UserName")]
14
public string UserName
15
{
16
get
{ return _userName; }
17
set
{ _userName = value; }
18
}
19
private string _sex;
20
[Property("Sex")]
21
public string Sex
22
{
23
get
{ return _sex; }
24
set
{ _sex = value; }
25
}
26
private IList _news;
27
[HasMany(typeof(News), Table = "News", ColumnKey = "User_Oid")]
28
public IList News
29
{
30
get
{ return _news; }
31
set
{ _news = value; }
32
}
33
#endregion
34
方法#region 方法
35
public static IList<Users> FindAll()
36
{
37
return (IList<Users>)FindAll(typeof(Users));
38
}
39
public override string ToString()
40
{
41
return this.UserName.ToString();
42
}
43
#endregion
44
}
1
[ActiveRecord("News")]
2
public class News:ActiveRecordBase
3

{
4
private int _oid;
5
[PrimaryKey(PrimaryKeyType.Identity)]
6
public int Oid
7
{
8
get
{ return _oid; }
9
set
{ _oid = value; }
10
}
11
private string _title;
12
[Property]
13
public string Title
14
{
15
get
{ return _title; }
16
set
{ _title = value; }
17
}
18
private string _context;
19
[Property]
20
public string Context
21
{
22
get
{ return _context; }
23
set
{ _context = value; }
24
}
25
private string _author;
26
[Property]
27
public string Author
28
{
29
get
{ return _author; }
30
set
{ _author = value; }
31
}
32
private DateTime _createTime;
33
[Property]
34
public DateTime CreateTime
35
{
36
get
{ return _createTime; }
37
set
{ _createTime = value; }
38
}
39
40
private Users _users;
41
[BelongsTo("User_Oid")]
42
public Users Users
43
{
44
get
{ return _users; }
45
set
{ _users = value; }
46
}
47
public static IList<News> FindAll()
48
{
49
return (IList<News>)FindAll(typeof(News));
50
}
51
HQL--查询出符合条件的记录#region HQL--查询出符合条件的记录
52
public static IList<News> FindByAuthor(string author)
53
{
54
SimpleQuery query = new SimpleQuery(typeof(News), "From News as n where n.Author=?", author);
55
return (IList<News>)ExecuteQuery(query);
56
}
57
#endregion
58
}
代码里我门使用了HQL语句进行了按新闻的发布者查询。使用了SimpleQuery这个类来实现,该类有4次重载。
1
HQL--查询出符合条件的记录#region HQL--查询出符合条件的记录
2
public static IList<News> FindByAuthor(string author)
3

{
4
SimpleQuery query = new SimpleQuery(typeof(News), "From News as n where n.Author=?", author);
5
return (IList<News>)ExecuteQuery(query);
6
}
7
#endregion
此查询示例我门通过程序来测试下.
1
private void Form1_Load(object sender, EventArgs e)
2

{
3
DataBindGridView();
4
}
5
private void DataBindGridView()
6

{
7
this.dataGridView1.DataSource = News.FindByAuthor("admin");
8
}
测试结果:(数据库里只两条记录,分别由admin,te)

在我们平时做程序的时候,查询肯定是有很复杂的,不只是想上面这样一条简单的根据指定条件查询.这方面更详细的介绍请参考相应资料.本文只是简单介绍了HQL的使用.
下面我门看来HQL的Select字句和聚集函数的使用,用一个查询数据库表里的记录条数示例说明.
1
public static int RecordCount()
2

{
3
ScalarQuery query = new ScalarQuery(typeof(News), "select count(*) from News");
4
return (int)ExecuteQuery(query);
5
}
还有些诸如SQL中常见的查询操作:(参考下面代码示例)
1
/**//// <summary>
2
/// 模糊查询
3
/// </summary>
4
/// <param name="title">新闻标题</param>
5
/// <returns>IList<News></returns> 6
public static IList<News> FindByTitle(string title)
7

{
8
SimpleQuery query=new SimpleQuery(typeof(News),"From News as n where n.Title like ?","%"+title+"%");
9
return (IList<News>)ExecuteQuery(query);
10
}
章节限制,关于or,between * and *等操作就不另做介绍.出了用HQL语句外,Castle还封装了NHibernate的表达式,通过表达式来查询数据我个人认为效果更好,至少比用HQL方便.
然而在实际的项目开发中我门所面临的查询远远不止是上面这么简单,出了上面这些查询操作外,Castle的查询基类是一个抽象类public abstract class ActiveRecordBaseQuery,用户可以通过继承他来实现自定义查询.或者实现查询
接口public interface IActiveRecordQuery;然后从写其方法object Execute(NHibernate.ISession session);具体实现我将在下一篇文章中介绍.
相信通过HQL查询可以解决我们开发中的绝大多数的复杂查询问题,如果结合NHibernate表达式使用更为灵活。文中部门内容来自网上共享资料,部门内容是个人意见,如发现有类似文章或相同内容纯属巧合.技术在于交流.
官方参考资料
Castle的官方网站http://www.castleproject.org