本节内容

  • 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)查询,子查询在以后详细实例中学习。注意:HQLkeyword不区分大写和小写。

注意:因为篇幅有限,我在这里只贴出了数据訪问层的代码,就是在业务逻辑层能够直接调用的方法。測试这些方法的代码就没有贴出来了。你能够下载本系列的源码细致看看測试这些方法的代码。这节,我们在上一节源码的基础上,在数据訪问层中新建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和allkeyword的使用方法和语义与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[]>();
}

实例分析

好的,以上主要的查询的确很easy,我们还是參考一下实例,分析一下我们怎样写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)的更多相关文章

  1. [转]NHibernate之旅(3):探索查询之NHibernate查询语言(HQL)

    本节内容 NHibernate中的查询方法 NHibernate查询语言(HQL) 1.from子句 2.select子句 3.where子句 4.order by子句 5.group by子句 实例 ...

  2. [转]NHibernate之旅(2):第一个NHibernate程序

    本节内容 开始使用NHibernate 1.获取NHibernate 2.建立数据库表 3.创建C#类库项目 4.设计Domain 4-1.设计持久化类 4-2.编写映射文件 5.数据访问层 5-1. ...

  3. NHibernate之旅系列文章导航

    NHibernate之旅系列文章导航 宣传语 NHibernate.NHibernate教程.NHibernate入门.NHibernate下载.NHibernate教程中文版.NHibernate实 ...

  4. Fluent NHibernate之旅

    Fluent NHibernate 之旅 导航篇: [原创]Fluent NHibernate之旅开篇: [原创]Fluent NHibernate之旅二--Entity Mapping: [原创]F ...

  5. hibernate 教程(3)—NHibernate查询语言HQL

    NHibernate之旅(3):探索查询之NHibernate查询语言(HQL) 本节内容 NHibernate中的查询方法 NHibernate查询语言(HQL) 1.from子句 2.select ...

  6. [转]NHibernate之旅(11):探索多对多关系及其关联查询

    本节内容 多对多关系引入 多对多映射关系 多对多关联查询 1.原生SQL关联查询 2.HQL关联查询 3.Criteria API关联查询 结语 多对多关系引入 让我们再次回顾在第二篇中建立的数据模型 ...

  7. [转]NHibernate之旅(10):探索父子(一对多)关联查询

    本节内容 关联查询引入 一对多关联查询 1.原生SQL关联查询 2.HQL关联查询 3.Criteria API关联查询 结语 关联查询引入 在NHibernate中提供了三种查询方式给我们选择:NH ...

  8. [转]NHibernate之旅(4):探索查询之条件查询(Criteria Query)

    本节内容 NHibernate中的查询方法 条件查询(Criteria Query) 1.创建ICriteria实例 2.结果集限制 3.结果集排序 4.一些说明 根据示例查询(Query By Ex ...

  9. [转]NHibernate之旅(12):初探延迟加载机制

    本节内容 引入 延迟加载 实例分析 1.一对多关系实例 2.多对多关系实例 结语 引入 通过前面文章的分析,我们知道了如何使用NHibernate,比如CRUD操作.事务.一对多.多对多映射等问题,这 ...

随机推荐

  1. make---GNU编译工具

    make命令是GNU的工程化编译工具,用于编译众多相互关联的源代码问价,以实现工程化的管理,提高开发效率. 知识扩展 无论是在linux 还是在Unix环境 中,make都是一个非常重要的编译命令.不 ...

  2. 页面打开pdf格式文件的方法

    <embed width=500 height=300 fullscreen=yes src="1.pdf" />

  3. WMI获取进程CPU占用率

    Monitor % Process CPU Usage (specific process) http://www.tek-tips.com/viewthread.cfm?qid=395765 for ...

  4. [ES2017] Iterate over properties of an object with ES2017 Object.entries()

    The Object.entries() function is an addition to the ECMAscript scpec in Es2017. This allows us to it ...

  5. Codeforces 240E. Road Repairs 最小树形图+输出路径

    最小树形图裸题,只是须要记录路径 E. Road Repairs time limit per test 2 seconds memory limit per test 256 megabytes i ...

  6. POJ 1006 Biorhythms (数论-中国剩余定理)

    Biorhythms Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 111285   Accepted: 34638 Des ...

  7. amlogic M8操作gpio bank

    參照规格书: r代表:读 a代表GPIOAO bank 0x28代表read bit echo r a 0x28 > /sys/class/amlogic/debug 操作GPIO口读取 w代表 ...

  8. js---11运算符,流程控制,真假

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  9. ps---报告当前系统的进程状态

    ps aux最初用到Unix Style中,而ps -ef被用在System V Style中,两者输出略有不同.现在的大部分Linux系统都是可以同时使用这两种方式的. linux上进程有5种状态: ...

  10. [AngularFire2 & Firestore] Example for collection and doc

    import {Injectable} from '@angular/core'; import {Skill} from '../models/skills'; import {AuthServic ...