在ActiveRecord中實現稍微復雜的一點的查詢,我們就不能用使用Find(id),FindAll()這兩個靜態的方法了,這時就需要使用HQL語句來實現,在平常使用Castle的時候我想大家都注意到在ActiveRecordBase類下,由於只提供了Find(id),FindAll()這樣兩個靜態的查詢方法,這兩個方法在我們查詢中還遠遠不夠,仍然不能解決實際開發中一些復雜的查詢,這方面ActiveRecord為我們提供了HQL語言的支持。
一.HQL語句介紹
HQL全名是Hibernate Query Language,它是一種完全面向對象的查詢語言。我門先來看一下HQL最基本的一些用法(類似SQL):
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")]
2public 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")]
2public 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次重載。
1HQL--查詢出符合條件的記錄#region HQL--查詢出符合條件的記錄
2public 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
此查詢示例我門通過程序來測試下.
1private void Form1_Load(object sender, EventArgs e)
2{
3 DataBindGridView();
4}
5private void DataBindGridView()
6{
7 this.dataGridView1.DataSource = News.FindByAuthor("admin");
8}
測試結果:(數據庫裡只兩條記錄,分別由admin,te)

在我們平時做程序的時候,查詢肯定是有很復雜的,不只是想上面這樣一條簡單的根據指定條件查詢.這方面更詳細的介紹請參考相應資料.本文只是簡單介紹了HQL的使用.
下面我門看來HQL的Select字句和聚集函數的使用,用一個查詢數據庫表裡的記錄條數示例說明.
1public 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>
6public 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