丹尼大叔

数学专业毕业,爱上编程的大叔,兴趣广泛。使用博客园这个平台分享我工作和业余的学习内容,以编程交友。有朋自远方来,不亦乐乎。

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

摘要

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方法执行批量数据的更新。

posted on 2016-07-22 23:56  丹尼大叔  阅读(731)  评论(0编辑  收藏  举报