目錄
寫在前面
上篇文章介紹了nhibernate在項目中的基本配置,包括數據庫連接字符串的設置,映射文件的配置及需注意的地方,這篇文章將介紹nhibernate的查詢方法。
文檔與系列文章
[NHibernate]持久化類(Persistent Classes)
[NHibernate]集合類(Collections)映射
[NHibernate]緩存(NHibernate.Caches)
[NHibernate]NHibernate.Tool.hbm2net
[NHibernate]Nhibernate如何映射sqlserver中image字段
查詢的幾種方式
nhibernate中常見的查詢方式有以下三種:
- NHibernate查詢語言(HQL,NHibernate Query Language)。
- 條件查詢(Criteria API,Query By Example(QBE)是Criteria API的一種特殊情況)。
- 原生SQL(Literal SQL,T-SQL、PL/SQL)。
HQL查詢
這篇文章着重介紹HQL查詢方式。
HQL(Hibernate Query Language)查詢提供了更加豐富的和靈活的查詢特性,因此Hibernate將HQL查詢方式立為官方推薦的標准查詢方式,HQL查詢在涵蓋Criteria查詢的所有功能的前提下,提供了類似標准SQL語句的查詢方式,同時也提供了更加面向對象的封裝。
完整的HQL語句形式如下:
Select/update/delete…… from …… where …… group by …… having …… order by …… asc/desc
其中的update/delete為Hibernate3中所新添加的功能,可見HQL查詢非常類似於標准SQL查詢。(來自百度百科)
注意:HQL是基於面向對象的查詢語言。
該怎樣理解這就話呢?和sql不同,HQL中的查詢的是對象的屬性。例如
1 /// <summary> 2 /// 根據客戶姓名進行模糊查詢 3 /// </summary> 4 /// <param name="strName">查詢條件</param> 5 /// <returns>滿足條件的客戶信息</returns> 6 public IList<Customer> SearchByName(string strName) 7 { 8 NHibernateHelper nhibernateHelper = new NHibernateHelper(); 9 ISession session = nhibernateHelper.GetSession(); 10 //from后面跟的是持久化類Customer而不是數據表名TB_Customer 11 return session.CreateQuery("from Customer as customer where customer.CustomerName like '%" + strName + "%'").List<Customer>(); 12 }
在from后面跟的是持久化類的名,而不是表名。否則會出現如下異常:
同樣也支持select,查詢多個屬性時返回的是IList<Object[]> object數組泛型集合。
1 /// <summary> 2 /// 根據客戶姓名進行模糊查詢 3 /// </summary> 4 /// <param name="strName">查詢條件</param> 5 /// <returns>滿足條件的客戶信息</returns> 6 public IList<object[]> SearchByName(string strName) 7 { 8 NHibernateHelper nhibernateHelper = new NHibernateHelper(); 9 ISession session = nhibernateHelper.GetSession(); 10 //from后面跟的是持久化類Customer而不是數據表名TB_Customer 11 return session.CreateQuery("select customer.CustomerID,customer.CustomerName,customer.CustomerAddress from Customer as customer where customer.CustomerName like '%" + strName + "%'").List<object[]>(); 12 }
當查詢單個屬性時,例如查詢所有客戶的id,此時返回IList<Guid>
1 /// <summary> 2 /// 獲得所有客戶的id 3 /// </summary> 4 /// <returns></returns> 5 public IList<Guid> GetAllCustomerID() 6 { 7 NHibernateHelper nhibernateHelper = new NHibernateHelper(); 8 ISession session = nhibernateHelper.GetSession(); 9 return session.CreateQuery("select customer.CustomerID from Customer as customer").List<Guid>(); 10 }
另外的order by ,group by,distinct的使用與sql類似,就不再舉例子了。
注意:在HQL中,也是大小寫不敏感的,也就是不區分大小寫的。
一個例子
where條件子句中除sql的大部分情況外,還支持命名參數和位置參數。
根據用戶名查詢客戶信息
1 /// <summary> 2 /// 根據姓名查詢客戶信息 3 /// </summary> 4 /// <param name="strName"></param> 5 /// <returns></returns> 6 public IList<Customer> GetCustomerByName(string strName) 7 { 8 NHibernateHelper nhibernateHelper = new NHibernateHelper(); 9 ISession session = nhibernateHelper.GetSession(); 10 //方式一 11 // return session.CreateQuery("from Customer c where c.CustomerName='" + strName + "'").List<Customer>(); 12 //方式二:位置型參數 13 //return session.CreateQuery("from Customer c where c.CustomerName=?") 14 // .SetString(0, strName) 15 // .List<Customer>(); 16 //寫法3:命名型參數(推薦) 17 return session.CreateQuery("from Customer c where c.CustomerName=:cn") 18 .SetString("cn", strName) 19 .List<Customer>(); 20 }
以上代碼,列出了常見的三種風格的HQL語句寫法。
方式一:類似ADO.NET中的一般查詢語句的寫法,此種寫法可能造成SQL注入,不建議使用。
方式二:ADO.NET風格的?參數,NHibernate的參數從0開始計數。
方式三:命名參數用:name的形式在查詢字符串中表示,這時IQuery接口把實際參數綁定到命名參數。(類似ADO.NET中參數化查詢,推薦這種查詢方式)。
我們監控一下方式三生成的sql語句:
通過上圖我們發現,在生成的sql中,查詢條件為:
customer0_.CustomerName=@p0',N'@p0 nvarchar(4000)',@p0=N'wolfy'
@p0參數,再執行存儲過程,將實參wolfy字符串賦給參數@p0了。
總結
HQL查詢是基於面向對象的,在使用查詢是from后面的是持久化類對象,而不是數據表表名,這點應該注意。其它的地方跟sql查詢比較類似,比如order by ,group by,統計函數的使用等。
在使用hql查詢時,推薦使用命名參數的方式查詢。
參考文章