Bienvenido al tutorial de ejemplo de consulta SQL nativa de Hibernate. Hemos analizado el lenguaje de consulta de Hibernate y los criterios de Hibernate en artículos anteriores. Hoy analizaremos la consulta SQL nativa de Hibernate con ejemplos.
Consulta SQL de Hibernate
Hibernate ofrece la opción de ejecutar consultas SQL nativas mediante el uso del objeto SQLQuery . La consulta SQL de Hibernate es muy útil cuando tenemos que ejecutar consultas específicas del proveedor de la base de datos que no son compatibles con la API de Hibernate. Por ejemplo, sugerencias de consulta o la palabra clave CONNECT en Oracle Database. Para escenarios normales, la consulta SQL de Hibernate no es el enfoque recomendado porque perdemos los beneficios relacionados con la asociación de Hibernate y la caché de primer nivel de Hibernate . Usaré la base de datos MySQL y las mismas tablas y configuraciones de datos que se usaron en el ejemplo de HQL , por lo que debe verificar eso primero para comprender las tablas y el mapeo de clases de modelo correspondientes.
Ejemplo de SQL nativo de Hibernate
Para la consulta SQL nativa de Hibernate, utilizamos Session.createSQLQuery(String query)el objeto SQLQuery para crearlo y ejecutarlo. Por ejemplo, si desea leer todos los registros de la tabla Employee, podemos hacerlo mediante el código que se muestra a continuación.
// Prep workSessionFactory sessionFactory = HibernateUtil.getSessionFactory();Session session = sessionFactory.getCurrentSession();// Get All EmployeesTransaction tx = session.beginTransaction();SQLQuery query = session.createSQLQuery("select emp_id, emp_name, emp_salary from Employee");ListObject[] rows = query.list();for(Object[] row : rows){Employee emp = new Employee();emp.setId(Long.parseLong(row[0].toString()));emp.setName(row[1].toString());emp.setSalary(Double.parseDouble(row[2].toString()));System.out.println(emp);}
Cuando ejecutamos el código anterior para la configuración de datos que tenemos, produce el siguiente resultado.
Hibernate: select emp_id, emp_name, emp_salary from EmployeeId= 1, Name= Pankaj, Salary= 100.0, {Address= null}Id= 2, Name= David, Salary= 200.0, {Address= null}Id= 3, Name= Lisa, Salary= 300.0, {Address= null}Id= 4, Name= Jack, Salary= 400.0, {Address= null}
Tenga en cuenta que list()el método devuelve la lista de matrices de objetos, debemos analizarlos explícitamente como doble, largo, etc. Nuestras clases Empleado y Dirección tienen las siguientes toString()implementaciones de métodos.
@Overridepublic String toString() {return "Id= " + id + ", Name= " + name + ", Salary= " + salary+ ", {Address= " + address + "}";}
@Overridepublic String toString() {return "AddressLine1= " + addressLine1 + ", City=" + city+ ", Zipcode=" + zipcode;}
Tenga en cuenta que nuestra consulta no devuelve datos de dirección, mientras que si usamos la consulta HQL "from Employee", también devuelve los datos de la tabla asociada.
Consulta SQL de Hibernate addScalar
Hibernate utiliza métodos ResultSetMetadatapara deducir el tipo de columnas devueltas por la consulta. Desde el punto de vista del rendimiento, podemos utilizar addScalar()métodos para definir el tipo de datos de la columna. Sin embargo, seguiríamos obteniendo los datos en forma de matriz de objetos.
//Get All Employees - addScalar examplequery = session.createSQLQuery("select emp_id, emp_name, emp_salary from Employee").addScalar("emp_id", new LongType()).addScalar("emp_name", new StringType()).addScalar("emp_salary", new DoubleType());rows = query.list();for(Object[] row : rows){Employee emp = new Employee();emp.setId(Long.parseLong(row[0].toString()));emp.setName(row[1].toString());emp.setSalary(Double.parseDouble(row[2].toString()));System.out.println(emp);}
La salida generada será la misma, sin embargo veremos una ligera mejora en el rendimiento cuando los datos sean grandes.
Hibernate Native SQL Múltiples tablas
Si queremos obtener datos de las tablas de Empleados y Direcciones, podemos simplemente escribir la consulta SQL para ello y analizar el conjunto de resultados.
query = session.createSQLQuery("select e.emp_id, emp_name, emp_salary,address_line1, city, zipcode from Employee e, Address a where a.emp_id=e.emp_id");rows = query.list();for(Object[] row : rows){Employee emp = new Employee();emp.setId(Long.parseLong(row[0].toString()));emp.setName(row[1].toString());emp.setSalary(Double.parseDouble(row[2].toString()));Address address = new Address();address.setAddressLine1(row[3].toString());address.setCity(row[4].toString());address.setZipcode(row[5].toString());emp.setAddress(address);System.out.println(emp);}
Para el código anterior, la salida producida será como la que se muestra a continuación.
Hibernate: select e.emp_id, emp_name, emp_salary,address_line1, city, zipcode from Employee e, Address a where a.emp_id=e.emp_idId= 1, Name= Pankaj, Salary= 100.0, {Address= AddressLine1= Albany Dr, City=San Jose, Zipcode=95129}Id= 2, Name= David, Salary= 200.0, {Address= AddressLine1= Arques Ave, City=Santa Clara, Zipcode=95051}Id= 3, Name= Lisa, Salary= 300.0, {Address= AddressLine1= BTM 1st Stage, City=Bangalore, Zipcode=560100}Id= 4, Name= Jack, Salary= 400.0, {Address= AddressLine1= City Centre, City=New Delhi, Zipcode=100100}
Entidad SQL nativa de Hibernate y unión
También podemos utilizar los métodos addEntity()y addJoin()para obtener los datos de la tabla asociada mediante la unión de tablas. Por ejemplo, los datos anteriores también se pueden recuperar de la siguiente manera.
//Join example with addEntity and addJoinquery = session.createSQLQuery("select {e.*}, {a.*} from Employee e join Address a ON e.emp_id=a.emp_id").addEntity("e",Employee.class).addJoin("a","e.address");rows = query.list();for (Object[] row : rows) { for(Object obj : row) { System.out.print(obj + "::"); } System.out.println("n");}//Above join returns both Employee and Address Objects in the arrayfor (Object[] row : rows) {Employee e = (Employee) row[0];System.out.println("Employee Info::"+e);Address a = (Address) row[1];System.out.println("Address Info::"+a);}
{[aliasname].*}se utiliza para devolver todas las propiedades de una entidad. Cuando utilizamos addEntity()y addJoin()con consultas de unión como las anteriores, devuelve ambos objetos, como se muestra arriba. El resultado producido por el código anterior es el siguiente.
Hibernate: select e.emp_id as emp_id1_1_0_, e.emp_name as emp_name2_1_0_, e.emp_salary as emp_sala3_1_0_, a.emp_id as emp_id1_0_1_, a.address_line1 as address_2_0_1_, a.city as city3_0_1_, a.zipcode as zipcode4_0_1_ from Employee e join Address a ON e.emp_id=a.emp_idId= 1, Name= Pankaj, Salary= 100.0, {Address= AddressLine1= Albany Dr, City=San Jose, Zipcode=95129}::AddressLine1= Albany Dr, City=San Jose, Zipcode=95129::Id= 2, Name= David, Salary= 200.0, {Address= AddressLine1= Arques Ave, City=Santa Clara, Zipcode=95051}::AddressLine1= Arques Ave, City=Santa Clara, Zipcode=95051::Id= 3, Name= Lisa, Salary= 300.0, {Address= AddressLine1= BTM 1st Stage, City=Bangalore, Zipcode=560100}::AddressLine1= BTM 1st Stage, City=Bangalore, Zipcode=560100::Id= 4, Name= Jack, Salary= 400.0, {Address= AddressLine1= City Centre, City=New Delhi, Zipcode=100100}::AddressLine1= City Centre, City=New Delhi, Zipcode=100100::Employee Info::Id= 1, Name= Pankaj, Salary= 100.0, {Address= AddressLine1= Albany Dr, City=San Jose, Zipcode=95129}Address Info::AddressLine1= Albany Dr, City=San Jose, Zipcode=95129Employee Info::Id= 2, Name= David, Salary= 200.0, {Address= AddressLine1= Arques Ave, City=Santa Clara, Zipcode=95051}Address Info::AddressLine1= Arques Ave, City=Santa Clara, Zipcode=95051Employee Info::Id= 3, Name= Lisa, Salary= 300.0, {Address= AddressLine1= BTM 1st Stage, City=Bangalore, Zipcode=560100}Address Info::AddressLine1= BTM 1st Stage, City=Bangalore, Zipcode=560100Employee Info::Id= 4, Name= Jack, Salary= 400.0, {Address= AddressLine1= City Centre, City=New Delhi, Zipcode=100100}Address Info::AddressLine1= City Centre, City=New Delhi, Zipcode=100100
Puede ejecutar ambas consultas en el cliente MySQL y observar que el resultado producido es el mismo.
mysql select e.emp_id as emp_id1_1_0_, e.emp_name as emp_name2_1_0_, e.emp_salary as emp_sala3_1_0_, a.emp_id as emp_id1_0_1_, a.address_line1 as address_2_0_1_, a.city as city3_0_1_, a.zipcode as zipcode4_0_1_ from Employee e join Address a ON e.emp_id=a.emp_id;+--------------+----------------+----------------+--------------+----------------+-------------+---------------+| emp_id1_1_0_ | emp_name2_1_0_ | emp_sala3_1_0_ | emp_id1_0_1_ | address_2_0_1_ | city3_0_1_ | zipcode4_0_1_ |+--------------+----------------+----------------+--------------+----------------+-------------+---------------+| 1 | Pankaj | 100 | 1 | Albany Dr | San Jose | 95129 || 2 | David | 200 | 2 | Arques Ave | Santa Clara | 95051 || 3 | Lisa | 300 | 3 | BTM 1st Stage | Bangalore | 560100 || 4 | Jack | 400 | 4 | City Centre | New Delhi | 100100 |+--------------+----------------+----------------+--------------+----------------+-------------+---------------+4 rows in set (0.00 sec)mysql select e.emp_id, emp_name, emp_salary,address_line1, city, zipcode from Employee e, Address a where a.emp_id=e.emp_id;+--------+----------+------------+---------------+-------------+---------+| emp_id | emp_name | emp_salary | address_line1 | city | zipcode |+--------+----------+------------+---------------+-------------+---------+| 1 | Pankaj | 100 | Albany Dr | San Jose | 95129 || 2 | David | 200 | Arques Ave | Santa Clara | 95051 || 3 | Lisa | 300 | BTM 1st Stage | Bangalore | 560100 || 4 | Jack | 400 | City Centre | New Delhi | 100100 |+--------+----------+------------+---------------+-------------+---------+4 rows in set (0.00 sec)mysql
Consulta SQL nativa de Hibernate con parámetros
También podemos pasar parámetros a las consultas SQL de Hibernate, como en el caso de JDBC PreparedStatement . Los parámetros se pueden configurar mediante el nombre y el índice, como se muestra en el siguiente ejemplo.
query = session.createSQLQuery("select emp_id, emp_name, emp_salary from Employee where emp_id = ?");ListObject[] empData = query.setLong(0, 1L).list();for (Object[] row : empData) {Employee emp = new Employee();emp.setId(Long.parseLong(row[0].toString()));emp.setName(row[1].toString());emp.setSalary(Double.parseDouble(row[2].toString()));System.out.println(emp);}query = session.createSQLQuery("select emp_id, emp_name, emp_salary from Employee where emp_id = :id");empData = query.setLong("id", 2L).list();for (Object[] row : empData) {Employee emp = new Employee();emp.setId(Long.parseLong(row[0].toString()));emp.setName(row[1].toString());emp.setSalary(Double.parseDouble(row[2].toString()));System.out.println(emp);}
La salida producida por el código anterior sería:
Hibernate: select emp_id, emp_name, emp_salary from Employee where emp_id = ?Id= 1, Name= Pankaj, Salary= 100.0, {Address= null}Hibernate: select emp_id, emp_name, emp_salary from Employee where emp_id = ?Id= 2, Name= David, Salary= 200.0, {Address= null}
Eso es todo por una breve introducción a Hibernate SQL Query, debes evitar su uso a menos que quieras ejecutar alguna consulta específica de base de datos.