NHibernate系列文章二十二:NHibernate查询之HQL查询(附程序下载)

时间:2022-12-18 21:39:56

摘要

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类所有实体对象:

         public IList<Customer> QueryAllHql()
{
return Session.CreateQuery("from Customer").List<Customer>();
}

from子句不支持符号“*”。

通过ISession的CreateQuery方法,传入HQL语句,生成IQuery对象,然后调用List方法立即执行查询。

2、as子句提供别名,as可以省略

         public IList<Customer> QueryAllHql()
{
return Session.CreateQuery("from Customer as c").List<Customer>();
}

3、select子句

指定列返回数组

         public IList<int> SelectIdHql()
{
return Session.CreateQuery("select distinct c.Id from Customer c").List<int>();
}

4、where子句

where子句跟SQL基本相同

         public IList<Customer> GetCustomerByNameHql(string firstName, string lastName)
{
return Session.CreateQuery("from Customer c where c.FirstName = :firstName and c.LastName = :lastName")
.SetString("firstName", firstName).SetString("lastName", lastName).List<Customer>();
}
  • 这里使用命名参数列表的形式,命名参数的格式是以符号":"开始的变量名,使用Set后面带参数类型的方法名对命名参数赋值。
  • 也可以拼接字符串,可能会引起SQL注入,不推荐使用。
  • 你还可以使用序号参数形式,序号参数使用符号"?"作为通配符,使用Set方法的重载方法,第一个参数类型是int,表示参数序号,第二个参数是参数值。

另一个例子,使用like模糊查询。

         public IList<Customer> GetCustomersStartWithHql()
{
var list = Session.CreateQuery("from Customer c where c.FirstName like 'J%'").List<Customer>();
return list;
}

where子句支持SQL大部分的条件查询语句,包括and、or、=、!=、<、>、标量函数等。

5、order by子句

         public IList<Customer> GetCustomersOrderByHql()
{
return Session.CreateQuery("from Customer c order by c.FirstName").List<Customer>();
}

6、关联查询

注意一点,关联查询的语句面向的是对象,因此可以直接在查询语句里使用对象的对象属性,比如c.Orders集合。

         /// <summary>
/// 按分组查询客户Id及客户关联的订单数量
/// </summary>
/// <returns></returns>
public IList<object[]> SelectOrderCountHql()
{
return Session.CreateQuery("select c.Id, c.Orders.size from Customer c").List<object[]>();
} /// <summary>
/// 查询所有订单数量大于2的客户信息
/// </summary>
/// <returns></returns>
public IList<Customer> GetCustomersOrderCountGreaterThanHql()
{
var list = Session.CreateQuery("from Customer c where c.Orders.size > 2").List<Customer>();
return list;
} /// <summary>
/// 查询在指定日期到当前时间内有下订单的客户信息
/// </summary>
/// <param name="orderDate"></param>
/// <returns></returns>
public IList<Customer> GetCustomersOrderDateGreatThanHql(DateTime orderDate)
{
var list = Session.CreateQuery("select distinct c from Customer c inner join c.Orders o where o.Ordered > :orderDate")
.SetDateTime("orderDate", orderDate).List<Customer>();
return list;
}

7、NHibernate的IQuery接口提供方法ExecuteUpdate执行批量修改

Session.CreateQuery("Insert/Update/Delete语句").ExecuteUpdate();

结语

NHibernate HQL查询的优点是很像原生SQL语言,很容易掌握。而且写起来比较灵活,能够满足绝大部分的查询任务。缺点也是显而易见的,将查询条件写在字符串里,不容易在编译时发现问题。最后介绍了通过IQuery接口ExecuteUpdate方法执行批量数据的更新。