NHibernate - Lenguaje de consulta de Hibernate

En este capítulo, cubriremos Hibernate Query Language. HQL se comparte entre Hibernate y NHibernate de Java.

  • Es el mecanismo de consulta más antiguo junto con Criteria.

  • Se implementó muy temprano y es una consulta basada en cadenas. API.

  • Lo accedes a través de ISession CreateQueryy es casi similar a SQL.

  • Utiliza muchas de las mismas palabras clave, pero tiene una sintaxis simplificada.

  • Es uno de los ejemplos más comunes, si está buscando cómo realizar una consulta, a menudo encontrará ejemplos de HQL.

El siguiente es un ejemplo simple de HQL:

var customers = session.CreateQuery("select c from Customer c where c.FirstName = 'Laverne'");
  • Aquí puede ver que seleccionan C del cliente, se parece mucho a SQL. Esta es una cadena opaca en lo que respecta a NHibernate, por lo que no sabe si es un HQL válido hasta el tiempo de ejecución, que es una de las desventajas.

  • Una de las fortalezas del proveedor LINQ es que puede compilar el tiempo de soporte.

  • Pero HQL es uno de los mecanismos de consulta más flexibles que se utilizan con frecuencia. Se dice que, si no hay otra forma de hacerlo, entonces hay una forma de hacerlo en HQL.

Echemos un vistazo a un ejemplo de simpe en el que recrearemos nuestras consultas LINQ utilizando HQL en su lugar. Puede obtener acceso a HQL llamando alsession.CreateQuery y pasar como parámetro usando una cadena 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; 
      } 
   } 
}
  • Esta cadena HQL se parece mucho a SQL, la principal diferencia es que FirstName es el nombre de la propiedad y no el nombre de la columna.

  • Entonces, si hay una discrepancia entre los dos, usa el nombre de la propiedad. Lo mismo, parece un nombre de tabla, pero en realidad es el nombre de la clase de la que estamos seleccionando.

  • Si la tabla back-end fuera nombrada como Clientes, todavía usaríamos Cliente en nuestra consulta HQL.

Ejecutemos esta aplicación y verá el siguiente resultado.

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...

Echemos un vistazo a otro ejemplo simple en el que recuperaremos todos aquellos clientes cuyo Nombre comienza con la letra H usando 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; 
      } 
   } 
}

Ejecutemos su aplicación nuevamente y verá que todos los clientes cuyo nombre comienza con H son devueltos por esta consulta.

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...

Podemos hacer cosas más complicadas como querer todos los pedidos donde los clientes con un recuento de pedidos es mayor que 9. A continuación se muestra la consulta HQL para el mismo.

var customers = session.CreateQuery("select c from Customer c 
   where size(c.Orders) > 9"); 
	
foreach (var customer in customers.List<Customer>()) { 
   Console.WriteLine(customer); 
}

También necesitamos indicar que necesitamos un tamaño aquí o un recuento o una longitud. En HQL, tenemos la opción de usar el método de tamaño especial como se muestra arriba.

La otra forma de escribir esto, si lo prefiere, es c.Orders.size, y esto tiene el efecto exacto.

var customers = session.CreateQuery("select c from Customer c 
   where c.Orders.size > 9"); 
	
foreach (var customer in customers.List<Customer>()) { 
   Console.WriteLine(customer); 
}

Ejecutemos esta aplicación.

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...

Puede ver que todos los clientes que tienen más de 9 pedidos se recuperan de la base de datos.