標籤:des blog http color io 使用 ar strong for
本節內容
- NHibernate中的查詢方法
- NHibernate查詢語言(HQL)
- 1.from子句
- 2.select子句
- 3.where子句
- 4.order by子句
- 5.group by子句
- 執行個體分析
- 結語
上一節,我們初步搭建了一個NHibernate程式,完成了映射Customer表並讀取資料功能,這一節和下一節我們初步探討一下在NHibernate中的查詢方法。我這之前還是先回憶一下上一節完成的東西,其中一張圖很多人回複說非常經典,簡單明了!還是看著圖。總結一下上一節三個重要的事情:建立資料庫表-----編寫持久化類-----編寫對應檔,然後配置使用了。
NHibernate中的查詢方法
在NHibernate中提供了很多查詢方式給我們選擇,這裡僅僅列舉了3種方式:NHibernate查詢語言(HQL,NHibernate Query Language)、條件查詢(Criteria API,Query By Example(QBE)是Criteria API的一種特殊情況)、原生SQL(Literal SQL,T-SQL、PL/SQL)。每個人有不同的喜好和特長,可以根據自己的情況選擇使用其中的一種或幾種。這一節我們介紹NHibernate查詢語言(HQL,NHibernate Query Language)。
NHibernate查詢語言(HQL)
NHibernate查詢語言(HQL,NHibernate Query Language)是NHibernate特有的基於物件導向的SQL查詢語言,它具有繼承、多態和關聯等特性。實際上是用OOP中的對象和屬性對應了資料庫中的表和列。
例如這一句:select c.Firstname from Customer c
Customer是資料庫表,Firstname是列;而對於HQL:Customer是一個對象,Firstname是Customer對象的屬性。相比之下SQL語句非常靈活,但是沒有編譯時間語法驗證支援。
本節介紹基礎文法:from子句,select子句,where子句,order by子句,group by子句並分別舉出可以啟動並執行執行個體。至於關聯和串連,多態(polymorphism)查詢,子查詢在以後具體執行個體中學習。注意:HQL關鍵字不區分大小寫。
注意:由於篇幅有限,我在這裡僅僅貼出了資料訪問層的代碼,就是在商務邏輯層可以直接調用的方法。測試這些方法的代碼就沒有貼出來了,你可以下載本系列的原始碼仔細看看測試這些方法的代碼。這節,我們在上一節原始碼的基礎上,在資料訪問層中建立QueryHql.cs類用於編寫HQL查詢方法,在資料訪問的測試層建立一QueryHqlFixture.cs類用於測試。
1.from子句
顧名思義,同SQL語句類似:
1.簡單用法:返回表中所有資料。
public IList<Customer> From(){ //返回所有Customer類的執行個體 return _session.CreateQuery("from Customer") .List<Customer>();}
2.使用別名:使用as來賦予表的別名,as可以省略。
public IList<Customer> FromAlias(){ //返回所有Customer類的執行個體,Customer賦予了別名customer return _session.CreateQuery("from Customer as customer") .List<Customer>();}
3.笛卡爾積:出現多個類,或者分別使用別名,返回笛卡爾積或者稱為“交叉”串連。
2.select子句
1.簡單用法:在結果集中返回指定的對象和屬性。
public IList<int> Select(){ //返回所有Customer的CustomerId return _session.CreateQuery("select c.CustomerId from Customer c") .List<int>();}
2.數組:用Object[]的數組返回多個對象和/或多個屬性,或者使用特殊的elements功能,注意一般要結合group by使用。注意,這裡是Object[]的數組,我們可以定義DTO對象集合返回,即使用型別安全的.NET對象。
public IList<object[]> SelectObject(){ return _session.CreateQuery("select c.Firstname, count(c.Firstname) from Customer c group by c.Firstname") .List<object[]>();}
3.統計函數:用Object[]的數組返回屬性的統計函數的結果,注意統計函數的變數也可以是集合count( elements(c.CustomerId) ) 。注意,這裡是Object[]的數組,我們可以定義DTO對象集合返回。
public IList<object[]> AggregateFunction(){ return _session.CreateQuery("select avg(c.CustomerId),sum(c.CustomerId),count(c) from Customer c") .List<object[]>();}
4.Distinct用法:distinct和all關鍵字的用法和語義與SQL相同。執行個體:擷取不同Customer的FirstName。
public IList<string> Distinct(){ return _session.CreateQuery("select distinct c.Firstname from Customer c") .List<string>();}
3.where子句
where子句讓你縮小你要返回的執行個體的列表範圍。
public IList<Customer> Where(){ return _session.CreateQuery("from Customer c where c.Firstname=‘YJing‘") .List<Customer>();}
where子句允許出現的運算式包括了在SQL中的大多數情況:
- 數學操作符:+, -, *, /
- 真假比較操作符:=, >=, <=, <>, !=, like
- 邏輯操作符:and, or, not
- 字串串連操作符:||
- SQL純量涵式:upper(),lower()
- 沒有首碼的( ):表示分組
- in, between, is null
- 位置參數:?
- 具名引數::name, :start_date, :x1
- SQL文字:‘foo‘, 69, ‘1970-01-01 10:00:01.0‘
- 枚舉值或常量:Color.Tabby
4.order by子句
按照任何返回的類或者組件的屬性排序:asc升序、desc降序。
public IList<Customer> Orderby(){ return _session.CreateQuery("from Customer c order by c.Firstname asc,c.Lastname desc") .List<Customer>();}
5.group by子句
按照任何返回的類或者組件的屬性進行分組。
public IList<object[]> Groupby(){ return _session.CreateQuery("select c.Firstname, count(c.Firstname) from Customer c group by c.Firstname") .List<object[]>();}
執行個體分析
好的,以上基本的查詢的確非常簡單,我們還是參考一下執行個體,分析一下我們如何寫HQL查詢吧!
執行個體1:按照FirstName查詢顧客:
public IList<Customer> GetCustomersByFirstname(string firstname){ //寫法1 //return _session.CreateQuery("from Customer c where c.Firstname=‘" + firstname + "‘") // .List<Customer>(); //寫法2:位置型參數 //return _session.CreateQuery("from Customer c where c.Firstname=?") // .SetString(0, firstname) // .List<Customer>(); //寫法3:命名型參數(推薦) return _session.CreateQuery("from Customer c where c.Firstname=:fn") .SetString("fn", firstname) .List<Customer>();}
書寫HQL參數有四種寫法:
- 寫法1:可能會引起SQL注入,不要使用。
- 寫法2:ADO.NET風格的?參數,NHibernate的參數從0開始計數。
- 寫法3:具名引數用:name的形式在查詢字串中表示,這時IQuery介面把實際參數綁定到具名引數。
- 寫法4:命名的參數列表,把一些參數添加到一個集合列表中的形式,比如可以查詢資料是否在這個集合列表中。
使用具名引數有一些好處:具名引數不依賴於它們在查詢字串中出現的順序;在同一個查詢中可以使用多次;它們的可讀性好。所以在書寫HQL使用參數的時候推薦命名型參數形式。
測試一下這個方法吧:看看資料庫中Firstname為“YJingLee”的記錄個數是否是1條,並可以判斷查詢出來的資料的FirstName屬性是不是“YJingLee”。
[Test]public void GetCustomerByFirstnameTest(){ IList<Customer> customers = _queryHQL.GetCustomersByFirstname("YJingLee"); Assert.AreEqual(1, customers.Count); foreach (var c in customers) { Assert.AreEqual("YJingLee", c.Firstname); }}
執行個體2:擷取顧客ID大於CustomerId的顧客:
public IList<Customer> GetCustomersWithCustomerIdGreaterThan(int customerId){ return _session.CreateQuery("from Customer c where c.CustomerId > :cid") .SetInt32("cid", customerId) .List<Customer>();}
結語
在這篇文章中,我們瞭解了NHibernate其中的一種查詢語言HQL,這些執行個體我爭取寫出來可以運行起來,大家下載源碼看看效果,一些資料需要按個人情況修改。例如查詢條件結果。下一節繼續介紹另外一種查詢語言!注意,這篇有的是返回IList<object[]>類型,在實際項目中不可能使用這個類型,我們需要使用一個對象,就是一個DTO轉換返回IList<ClassDTO>類型。
[轉]NHibernate之旅(3):探索查詢之NHibernate查詢語言(HQL)