Using Named Queries
使用命名查询
和SQL一样,不应该在HQL中混有业务逻辑.那样的话代码将没有可读性,而且查询几乎是不可能执行单元测试.本节介绍如何将HQL查询迁移出我们的代码,以提高可读性和可测试性,甚至于通过预编译查询提高程序性能.
步骤
1. 完成本章简介中的通用步骤.将新建的控制台程序命名为NamedQueryExample.
2. 添加名为GetBookByISBN.hbm.xml的映射文档,别忘了将其设置为嵌入式资源,代码如下:
View Code
<?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"> <query name="GetBookByISBN"> <![CDATA[ from Book b where b.ISBN = :isbn ]]> </query> </hibernate-mapping>
3. 在App.config中,在<mapping assembly="Eg.Core"/>元素下面添加<mapping assembly="NamedQueryExample"/>.
4. 在Queries类中,添加下面的方法:
View Code
public Book GetBookByISBN(string isbn) { return _session.GetNamedQuery("GetBookByISBN") .SetString("isbn", isbn) .UniqueResult<Book>(); }
5. 在Program.cs中, 为RunQueries方法添加下述代码:
View Code
static void RunQueries(ISession session) { var queries = new Queries(session); Show("This book:", queries.GetBookByISBN( "978-1-849513-04-3")); }
6. 编译运行,结果如下图所示:
原理
这个示例中,使用了熟悉的GetBookByISBN查询.使用GetNamedQuery创建了一个标准的HQL IQuery对象.这次我们在映射文档中定义查询,而不是在代码中.
这是在NHibernate中使用查询的最理想的方法.因为使用任何HQL查询,NHibernate都将对实体的映射和模式进行解析、编译和验证.因为她是一个映射文档,所以在构建会话工厂的时候就会提前完成这些工作.如果有任何错误发生,在构建会话工厂的时候都会抛出异常,而不是在执行查询时.编译时错误总比运行时异常更好.她提供了一个显而易见的预先检查.另外,这种预先解析和编译被缓存供以后使用. NHibernate只需要对必要的SQL构建一次.
扩展
MultiQuery为命名查询提供了便捷的实现方式,代码如下:
View Code
var multiQuery = session.CreateMultiQuery() .AddNamedQuery<int>("count", "CountAllProducts") .Add<Product>("page", pageQuery);
在上面的代码中,我们使用了这种便捷方式添加了count查询.为了设置结果的起始位置和结果数的最大值,我们需要单独构建我们的页面查询.
命名的SQL查询(Named SQL queries)
在NHibernate中,除了HQL外,也可以在SQL中创建命名查询.但是这种情况,只有在HQL无法工作或是SQL查询已经优化时,才会使用.在C#代码中使用SQL命名查询和使用HQL查询是等价的.这使得我们在不改变应用程序代码的情况下,可以先使用HQL创建查询,而后替换为更快的SQL查询,这只需修改映射文档.代码如下:
View Code
<?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"> <sql-query name="GetBookByISBN_SQL"> <return alias="b" class="Eg.Core.Book, Eg.Core" /> <![CDATA[ SELECT b.Id AS [b.Id], b.Name AS [b.Name], b.Description AS [b.Description], b.UnitPrice AS [b.UnitPrice], b.Author AS [b.Author], b.ISBN as [b.ISBN] FROM Product b WHERE b.ProductType = 'Eg.Core.Book' AND b.ISBN = :isbn ]]> <query-param name="isbn" type="string"/> </sql-query> </hibernate-mapping>
return元素定义了alias(这是我们在查询结果中使用的别名),以及该数据中的实体.
HQL插件(HQL AddIn)
Jose Romaniello制作的开源HQL插件集成在Visual Studio 2010中,该插件在编写HQL查询时,为您提供了提供智能感知,高亮显示和语法校验
更多信息请浏览站点:http://hqladdin.codeplex.com/.


浙公网安备 33010602011771号