- NHibernate 教程
- NHibernate - 首页
- NHibernate - 概述
- NHibernate - 架构
- NHibernate - ORM
- NHibernate - 环境搭建
- NHibernate - 快速入门
- NHibernate - 基础ORM
- NHibernate - 基本CRUD操作
- NHibernate - 分析器
- 为映射文件添加IntelliSense
- NHibernate - 数据类型映射
- NHibernate - 配置
- NHibernate - 重写配置
- NHibernate - 批处理大小
- NHibernate - 缓存
- NHibernate - 组件映射
- NHibernate - 关系
- NHibernate - 集合映射
- NHibernate - 级联操作
- NHibernate - 延迟加载
- NHibernate - 反向关系
- NHibernate - Load/Get
- NHibernate - LINQ
- NHibernate - 查询语言
- NHibernate - Criteria 查询
- NHibernate - QueryOver 查询
- NHibernate - 原生SQL
- NHibernate - Fluent Hibernate
- NHibernate 有用资源
- NHibernate - 快速指南
- NHibernate - 有用资源
- NHibernate - 讨论
NHibernate - Hibernate 查询语言
本章将介绍Hibernate查询语言(HQL)。HQL在Java的Hibernate和NHibernate中都是通用的。
它是与Criteria一起最古老的查询机制。
它很早就实现了,是一个基于字符串的查询API。
您可以通过ISession CreateQuery访问它,它与SQL非常相似。
它使用了许多相同的关键字,但语法更简化。
如果您正在寻找如何执行查询,它是最常见的示例之一,您通常会找到HQL示例。
以下是一个简单的HQL示例:
var customers = session.CreateQuery("select c from Customer c where c.FirstName = 'Laverne'");
在这里您可以看到它从customer中选择C,它看起来很像SQL。就NHibernate而言,这是一个不透明的字符串,因此您在运行时之前不知道它是否是一个有效的HQL,这也是它的缺点之一。
LINQ提供程序的优势之一是可以获得编译时支持。
但是,HQL是最灵活且经常使用的查询机制之一。据说,如果没有其他方法可以做到,那么就有一种方法可以在HQL中做到。
让我们来看一个简单的例子,我们将使用HQL而不是LINQ查询来重现我们的LINQ查询。您可以通过调用session.CreateQuery并使用HQL字符串作为参数来访问HQL。
using System; using System.Data; using System.Linq; using System.Reflection; using HibernatingRhinos.Profiler.Appender.NHibernate; using NHibernate.Cfg; using NHibernate.Criterion; using NHibernate.Dialect; using NHibernate.Driver; using NHibernate.Linq; namespace NHibernateDemo { internal class Program { private static void Main() { var cfg = ConfigureNHibernate(); var sessionFactory = cfg.BuildSessionFactory(); using(var session = sessionFactory.OpenSession()) using(var tx = session.BeginTransaction()) { var customers = session.CreateQuery("select c from Customer c where c.FirstName = 'Laverne'"); foreach (var customer in customers.List<Customer>()) { Console.WriteLine(customer); } tx.Commit(); } Console.WriteLine("Press <ENTER> to exit..."); Console.ReadLine(); } private static Configuration ConfigureNHibernate() { NHibernateProfiler.Initialize(); var cfg = new Configuration(); cfg.DataBaseIntegration(x => { x.ConnectionStringName = "default"; x.Driver<SqlClientDriver>(); x.Dialect<MsSql2008Dialect>(); x.IsolationLevel = IsolationLevel.RepeatableRead; x.Timeout = 10; x.BatchSize = 10; }); cfg.SessionFactory().GenerateStatistics(); cfg.AddAssembly(Assembly.GetExecutingAssembly()); return cfg; } } }
这个HQL字符串看起来很像SQL,主要区别在于FirstName是属性名称而不是列名。
因此,如果两者之间存在差异,则使用属性名称。同样,它看起来像表名,但实际上是我们从中选择的类的名称。
如果后端表命名为Customers,我们仍然会在HQL查询中使用Customer。
让我们运行这个应用程序,您将看到以下输出。
Laverne Hegmann (4e97c816-6bce-11e1-b095-6cf049ee52be) Points: 74 HasGoldStatus: True MemberSince: 4/4/2009 12:00:00 AM (Utc) CreditRating: Neutral AverageRating: 0 Orders: Order Id: 4ea14d96-6bce-11e1-b095-6cf049ee52be Order Id: 4ea14d96-6bce-11e1-b096-6cf049ee52be Order Id: 4ea14d96-6bce-11e1-b097-6cf049ee52be Order Id: 4ea14d96-6bce-11e1-b098-6cf049ee52be Press <ENTER> to exit...
让我们来看另一个简单的例子,我们将使用HQL检索所有FirstName以字母H开头的客户。
using System; using System.Data; using System.Linq; using System.Reflection; using HibernatingRhinos.Profiler.Appender.NHibernate; using NHibernate.Cfg; using NHibernate.Criterion; using NHibernate.Dialect; using NHibernate.Driver; using NHibernate.Linq; namespace NHibernateDemo { internal class Program { private static void Main() { var cfg = ConfigureNHibernate(); var sessionFactory = cfg.BuildSessionFactory(); using(var session = sessionFactory.OpenSession()) using(var tx = session.BeginTransaction()) { var customers = session.CreateQuery("select c from Customer c where c.FirstName like 'H%'"); foreach (var customer in customers.List<Customer>()) { Console.WriteLine(customer); } tx.Commit(); } Console.WriteLine("Press <ENTER> to exit..."); Console.ReadLine(); } private static Configuration ConfigureNHibernate() { NHibernateProfiler.Initialize(); var cfg = new Configuration(); cfg.DataBaseIntegration(x => { x.ConnectionStringName = "default"; x.Driver<SqlClientDriver>(); x.Dialect<MsSql2008Dialect>(); x.IsolationLevel = IsolationLevel.RepeatableRead; x.Timeout = 10; x.BatchSize = 10; }); cfg.SessionFactory().GenerateStatistics(); cfg.AddAssembly(Assembly.GetExecutingAssembly()); return cfg; } } }
让我们再次运行您的应用程序,您将看到所有名称以H开头的客户都将从该查询返回。
Herman Crooks (4ead3480-6bce-11e1-b15c-6cf049ee52be) Points: 74 HasGoldStatus: True MemberSince: 12/3/2010 12:00:00 AM (Utc) CreditRating: Neutral AverageRating: 0 Orders: Order Id: 4ead3480-6bce-11e1-b15d-6cf049ee52be Order Id: 4ead3480-6bce-11e1-b15e-6cf049ee52be Order Id: 4ead3480-6bce-11e1-b15f-6cf049ee52be Order Id: 4ead3480-6bce-11e1-b160-6cf049ee52be Order Id: 4ead3480-6bce-11e1-b161-6cf049ee52be Order Id: 4ead3480-6bce-11e1-b162-6cf049ee52be Order Id: 4ead3480-6bce-11e1-b163-6cf049ee52be Hudson Bins (4ec03f80-6bce-11e1-b2b7-6cf049ee52be) Points: 56 HasGoldStatus: False MemberSince: 10/20/2008 12:00:00 AM (Utc) CreditRating: Terrible AverageRating: 0 Orders: Order Id: 4ec03f80-6bce-11e1-b2b8-6cf049ee52be Order Id: 4ec03f80-6bce-11e1-b2b9-6cf049ee52be Order Id: 4ec03f80-6bce-11e1-b2ba-6cf049ee52be Order Id: 4ec03f80-6bce-11e1-b2bb-6cf049ee52be Order Id: 4ec03f80-6bce-11e1-b2bc-6cf049ee52be Order Id: 4ec03f80-6bce-11e1-b2bd-6cf049ee52be Order Id: 4ec03f80-6bce-11e1-b2be-6cf049ee52be Order Id: 4ec03f80-6bce-11e1-b2bf-6cf049ee52be Hettie Feest (4ec50240-6bce-11e1-b300-6cf049ee52be) Points: 82 HasGoldStatus: False MemberSince: 4/10/2009 12:00:00 AM (Utc) CreditRating: Neutral AverageRating: 0 Orders: Order Id: 4ec50240-6bce-11e1-b301-6cf049ee52be Order Id: 4ec50240-6bce-11e1-b302-6cf049ee52be Order Id: 4ec50240-6bce-11e1-b303-6cf049ee52be Press <ENTER> to exit...
我们可以做更复杂的事情,例如想要所有订单,其中客户的订单数量大于9。以下是相同的HQL查询。
var customers = session.CreateQuery("select c from Customer c where size(c.Orders) > 9"); foreach (var customer in customers.List<Customer>()) { Console.WriteLine(customer); }
我们还需要指出我们需要在这里使用大小、计数或长度。在HQL中,我们可以选择使用上面显示的特殊size方法。
如果您愿意,另一种写法是c.Orders.size,这具有完全相同的效果。
var customers = session.CreateQuery("select c from Customer c where c.Orders.size > 9"); foreach (var customer in customers.List<Customer>()) { Console.WriteLine(customer); }
让我们运行此应用程序。
Lindsay Towne (4ea3aef6-6bce-11e1-b0cb-6cf049ee52be) Points: 50 HasGoldStatus: False MemberSince: 4/13/2007 12:00:00 AM (Utc) CreditRating: VeryGood AverageRating: 0 Orders: Order Id: 4ea3aef6-6bce-11e1-b0cc-6cf049ee52be Order Id: 4ea3aef6-6bce-11e1-b0cd-6cf049ee52be Order Id: 4ea3aef6-6bce-11e1-b0ce-6cf049ee52be Order Id: 4ea3aef6-6bce-11e1-b0cf-6cf049ee52be Order Id: 4ea3aef6-6bce-11e1-b0d0-6cf049ee52be Order Id: 4ea3aef6-6bce-11e1-b0d1-6cf049ee52be Order Id: 4ea3aef6-6bce-11e1-b0d2-6cf049ee52be Order Id: 4ea3aef6-6bce-11e1-b0d3-6cf049ee52be Order Id: 4ea3aef6-6bce-11e1-b0d4-6cf049ee52be Order Id: 4ea3aef6-6bce-11e1-b0d5-6cf049ee52be Wyman Hammes (4ea61056-6bce-11e1-b0e2-6cf049ee52be) Points: 32 HasGoldStatus: False MemberSince: 2/5/2011 12:00:00 AM (Utc) CreditRating: Good AverageRating: 0 Orders: Order Id: 4ea61056-6bce-11e1-b0e3-6cf049ee52be Order Id: 4ea61056-6bce-11e1-b0e4-6cf049ee52be Order Id: 4ea61056-6bce-11e1-b0e5-6cf049ee52be Order Id: 4ea61056-6bce-11e1-b0e6-6cf049ee52be Order Id: 4ea61056-6bce-11e1-b0e7-6cf049ee52be Order Id: 4ea61056-6bce-11e1-b0e8-6cf049ee52be Order Id: 4ea61056-6bce-11e1-b0e9-6cf049ee52be Order Id: 4ea61056-6bce-11e1-b0ea-6cf049ee52be Order Id: 4ea61056-6bce-11e1-b0eb-6cf049ee52be Order Id: 4ea61056-6bce-11e1-b0ec-6cf049ee52be Press <ENTER> to exit...
您可以看到所有拥有超过9个订单的客户都从数据库中检索。