摘要
NHibernate提供了多种查询方式,最早的HQL语言查询、Criteria查询和SQL Query,到NHibernate 3.0的Linq NHibernate,NHIbernate 4.0又添加了Query Over。每种方式各有优缺点,任何一个SQL查询可以使用任何查询方式查询。根据程序员每种方式掌握的情况,可以使用不同的查询方式。本篇文章介绍HQL语言查询。HQL(Hibernate Query Language)是NHibernate特有的面向对象查询语言,他具有继承、多态的特点。很像原生SQL,但是稍有区别。
下面以前面几篇文章介绍的一对多、多对多对象模型为基础,介绍HQL。
本篇文章的代码可以到NHibernate查询下载
1、from子句
from子句很简单,他的格式是
from 实体类类名
查询Customer类所有实体对象:
1 public IList<Customer> QueryAllHql() 2 { 3 return Session.CreateQuery("from Customer").List<Customer>(); 4 }
from子句不支持符号“*”。
通过ISession的CreateQuery方法,传入HQL语句,生成IQuery对象,然后调用List方法立即执行查询。
2、as子句提供别名,as可以省略
1 public IList<Customer> QueryAllHql() 2 { 3 return Session.CreateQuery("from Customer as c").List<Customer>(); 4 }
3、select子句
指定列返回数组
1 public IList<int> SelectIdHql() 2 { 3 return Session.CreateQuery("select distinct c.Id from Customer c").List<int>(); 4 }
4、where子句
where子句跟SQL基本相同
1 public IList<Customer> GetCustomerByNameHql(string firstName, string lastName) 2 { 3 return Session.CreateQuery("from Customer c where c.FirstName = :firstName and c.LastName = :lastName") 4 .SetString("firstName", firstName).SetString("lastName", lastName).List<Customer>(); 5 }
- 这里使用命名参数列表的形式,命名参数的格式是以符号":"开始的变量名,使用Set后面带参数类型的方法名对命名参数赋值。
- 也可以拼接字符串,可能会引起SQL注入,不推荐使用。
- 你还可以使用序号参数形式,序号参数使用符号"?"作为通配符,使用Set方法的重载方法,第一个参数类型是int,表示参数序号,第二个参数是参数值。
另一个例子,使用like模糊查询。
1 public IList<Customer> GetCustomersStartWithHql() 2 { 3 var list = Session.CreateQuery("from Customer c where c.FirstName like 'J%'").List<Customer>(); 4 return list; 5 }
where子句支持SQL大部分的条件查询语句,包括and、or、=、!=、<、>、标量函数等。
5、order by子句
1 public IList<Customer> GetCustomersOrderByHql() 2 { 3 return Session.CreateQuery("from Customer c order by c.FirstName").List<Customer>(); 4 }
6、关联查询
注意一点,关联查询的语句面向的是对象,因此可以直接在查询语句里使用对象的对象属性,比如c.Orders集合。
1 /// <summary> 2 /// 按分组查询客户Id及客户关联的订单数量 3 /// </summary> 4 /// <returns></returns> 5 public IList<object[]> SelectOrderCountHql() 6 { 7 return Session.CreateQuery("select c.Id, c.Orders.size from Customer c").List<object[]>(); 8 } 9 10 /// <summary> 11 /// 查询所有订单数量大于2的客户信息 12 /// </summary> 13 /// <returns></returns> 14 public IList<Customer> GetCustomersOrderCountGreaterThanHql() 15 { 16 var list = Session.CreateQuery("from Customer c where c.Orders.size > 2").List<Customer>(); 17 return list; 18 } 19 20 /// <summary> 21 /// 查询在指定日期到当前时间内有下订单的客户信息 22 /// </summary> 23 /// <param name="orderDate"></param> 24 /// <returns></returns> 25 public IList<Customer> GetCustomersOrderDateGreatThanHql(DateTime orderDate) 26 { 27 var list = Session.CreateQuery("select distinct c from Customer c inner join c.Orders o where o.Ordered > :orderDate") 28 .SetDateTime("orderDate", orderDate).List<Customer>(); 29 return list; 30 }
7、NHibernate的IQuery接口提供方法ExecuteUpdate执行批量修改
Session.CreateQuery("Insert/Update/Delete语句").ExecuteUpdate();
结语
NHibernate HQL查询的优点是很像原生SQL语言,很容易掌握。而且写起来比较灵活,能够满足绝大部分的查询任务。缺点也是显而易见的,将查询条件写在字符串里,不容易在编译时发现问题。最后介绍了通过IQuery接口ExecuteUpdate方法执行批量数据的更新。