Учебники

NHibernate — Язык запросов Hibernate

В этой главе мы рассмотрим 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 заказов, извлекаются из базы данных.