В этой главе мы рассмотрим Hibernate Query Language. HQL используется в Hibernate и NHibernate.
-
Это самый старый механизм запросов наряду с критериями .
-
Он был реализован очень рано, и это API запросов на основе строк.
-
Вы получаете к нему доступ через ISession CreateQuery , и это почти похоже на SQL.
-
Он использует много одинаковых ключевых слов, но имеет упрощенный синтаксис.
-
Это один из самых распространенных примеров. Если вы ищете способ выполнить запрос, вы часто найдете примеры HQL.
Это самый старый механизм запросов наряду с критериями .
Он был реализован очень рано, и это 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.
Итак, здесь вы можете видеть, что они выбирают C из клиентов, это очень похоже на SQL. Это непрозрачная строка для NHibernate, так что вы не знаете, является ли это допустимым HQL до времени выполнения, что является одним из недостатков.
Одной из сильных сторон поставщика LINQ является то, что вы можете получить поддержку времени компиляции.
Но HQL — это один из наиболее гибких механизмов часто используемых запросов. Говорят, что если нет другого способа сделать это, то есть способ сделать это на HQL.
Давайте посмотрим на пример simpe, в котором мы воссоздадим наши запросы 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-запросе.
Эта строка 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...
Давайте рассмотрим еще один простой пример, в котором мы получим всех тех клиентов, чье FirstName начинается с буквы 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 заказов, извлекаются из базы данных.