NHibernate - язык запросов Hibernate
В этой главе мы рассмотрим язык запросов Hibernate. HQL используется как в Java Hibernate, так и в NHibernate.
Это самый старый механизм запросов наряду с Criteria.
Он был реализован очень рано и представляет собой строковый запрос. API.
Вы получаете доступ к нему через ISession CreateQuery, и он почти похож на SQL.
Он использует многие из тех же ключевых слов, но имеет упрощенный синтаксис.
Это один из наиболее распространенных примеров. Если вы ищете, как выполнить запрос, вы часто найдете примеры HQL.
Ниже приведен простой пример HQL -
var customers = session.CreateQuery("select c from Customer c where c.FirstName = 'Laverne'");
Здесь вы можете видеть, что они выбирают C у клиента, это очень похоже на SQL. Что касается NHibernate, это непрозрачная строка, поэтому вы не знаете, является ли это допустимым HQL до времени выполнения, что является одним из недостатков.
Одна из сильных сторон поставщика LINQ - это возможность получить поддержку во время компиляции.
Но HQL - один из наиболее часто используемых гибких механизмов запросов. Говорят, что если нет другого способа сделать это, то есть способ сделать это в HQL.
Давайте посмотрим на простой пример, в котором мы воссоздадим наши запросы LINQ, используя вместо этого HQL. Вы можете получить доступ к HQL, позвонив вsession.CreateQuery и передать как параметр, используя строку 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 - это имя свойства, а не имя столбца.
Итак, если между ними есть расхождение, вы используете имя свойства. То же самое, это похоже на имя таблицы, но на самом деле это имя класса, из которого мы выбираем.
Если бы внутренняя таблица была названа «Клиенты», мы все равно использовали бы «Клиента» в нашем запросе HQL.
Давайте запустим это приложение, и вы увидите следующий результат.
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...
Давайте рассмотрим еще один простой пример, в котором мы извлечем всех тех клиентов, чье имя начинается с буквы H, с помощью 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 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 у нас есть возможность использовать метод специального размера, как показано выше.
Другой способ написать это, если хотите, - 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 заказов, извлекаются из базы данных.