Tutorials  /  Java

Hibernate Native SQL Query Example: Anleitung und Beispiele

Ccentron Redaktion · Dezember 2024 ·4 Min. Lesezeit ·Java, Tutorial

In früheren Artikeln haben wir uns Hibernate Query Language und Hibernate Criteria angesehen. Heute werden wir uns Hibernate Native SQL Query mit Beispielen ansehen.

Hibernate SQL Query

Hibernate bietet die Möglichkeit, native SQL-Abfragen mit dem SQLQuery-Objekt auszuführen. Hibernate SQL Query ist sehr nützlich, wenn wir datenbankspezifische Abfragen ausführen müssen, die von der Hibernate-API nicht unterstützt werden, z. B. Abfragehinweise oder das CONNECT-Schlüsselwort in Oracle-Datenbanken.

Für normale Szenarien ist Hibernate SQL Query nicht die empfohlene Methode, da wir Vorteile in Bezug auf Hibernate-Assoziationen und den Hibernate-First-Level-Cache verlieren. Ich werde die MySQL-Datenbank sowie dieselben Tabellen und Dateneinstellungen wie im HQL-Beispiel verwenden. Sie sollten sich dieses zuerst ansehen, um die Tabellen und die entsprechende Zuordnung der Modellklassen zu verstehen.

VM

Passende Infrastruktur bei centron

Java-Anwendungen im Dauerbetrieb: ccloud³ VMs ab 3,12 € im Monat mit vollem Root-Zugriff, stundengenau abgerechnet. Cloud Server mieten →

Beispiel

Für Hibernate Native SQL Query verwenden wir Session.createSQLQuery(String query), um das SQLQuery-Objekt zu erstellen und auszuführen. Wenn Sie z. B. alle Datensätze aus der Employee-Tabelle lesen möchten, können wir dies mit folgendem Code tun:

Code
// Prep work
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.getCurrentSession();

// Get All Employees
Transaction tx = session.beginTransaction();
SQLQuery query = session.createSQLQuery("select emp_id, emp_name, emp_salary from Employee");
List<Object[]> 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);
}

Wenn wir den obigen Code für das eingerichtete Datenset ausführen, erhalten wir folgende Ausgabe:

Code
Hibernate: select emp_id, emp_name, emp_salary from Employee
Id= 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}

Beachten Sie, dass die list()-Methode eine Liste von Objektarrays zurückgibt. Wir müssen sie explizit in double, long usw. analysieren. Unsere Employee- und Address-Klassen haben folgende Implementierungen der toString()-Methode:

Code
@Override
public String toString() {
    return "Id= " + id + ", Name= " + name + ", Salary= " + salary
            + ", {Address= " + address + "}";
}
Code
@Override
public String toString() {
    return "AddressLine1= " + addressLine1 + ", City=" + city
            + ", Zipcode=" + zipcode;
}

Beachten Sie, dass unsere Abfrage keine Adressdaten zurückgibt, während die HQL-Abfrage "from Employee" auch die Daten der zugehörigen Tabelle zurückgibt.

Hibernate SQL Query addScalar

Hibernate verwendet ResultSetMetadata, um den Typ der von der Abfrage zurückgegebenen Spalten abzuleiten. Aus Performance-Sicht können wir die Methode addScalar() verwenden, um den Datentyp der Spalte zu definieren. Die Daten würden jedoch weiterhin in Form eines Objektarrays vorliegen:

Code
// Get All Employees - addScalar example
query = 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);
}

Die generierte Ausgabe wird dieselbe sein, wir werden jedoch eine leichte Leistungsverbesserung feststellen, wenn die Datenmenge groß ist.

Hibernate SQL Abfragen über mehrere Tabellen

Wenn wir Daten aus den Tabellen Employee und Address abrufen möchten, können wir die entsprechende SQL-Abfrage schreiben und das Ergebnis analysieren.

Code
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);
}

Für den obigen Code wird die folgende Ausgabe generiert:

Code
Hibernate: select e.emp_id, emp_name, emp_salary, address_line1, city, zipcode from Employee e, Address a where a.emp_id=e.emp_id
Id= 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}

Hibernate Native SQL Entity und Join

Wir können auch die Methoden addEntity() und addJoin() verwenden, um Daten aus verknüpften Tabellen über Joins abzurufen. Zum Beispiel können die obigen Daten auch wie folgt abgerufen werden:

Code
// Join example with addEntity and addJoin
query = 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 array
for (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].*} wird verwendet, um alle Eigenschaften einer Entität zurückzugeben. Wenn wir addEntity() und addJoin() mit Join-Abfragen wie oben verwenden, gibt es beide Objekte zurück, wie oben gezeigt. Die generierte Ausgabe sieht wie folgt aus:

Code
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_id
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=95129
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=95051
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=560100
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

Sie können beide Abfragen im MySQL-Client ausführen und feststellen, dass die erzeugte Ausgabe identisch ist.

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

Hibernate SQL-Abfrage mit Parametern

Wir können auch Parameter an die Hibernate SQL-Abfragen übergeben, ähnlich wie bei JDBC PreparedStatement. Die Parameter können sowohl mit Namen als auch mit Index gesetzt werden, wie im folgenden Beispiel gezeigt:

Code
query = session
        .createSQLQuery("select emp_id, emp_name, emp_salary from Employee where emp_id = ?");
List<Object[]> 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);
}

Die durch den obigen Code erzeugte Ausgabe wäre:

Code
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
Id= 2, Name= David, Salary= 200.0, {Address= null}

Das war eine kurze Einführung in Hibernate SQL Query. Sie sollten diese Methode vermeiden, es sei denn, Sie müssen datenbankspezifische Abfragen ausführen.

Jetzt 200 € Guthaben sichern

Testen Sie Ihr Setup auf ccloud³

Registrieren Sie sich in der ccloud³ und erhalten Sie 200 € Startguthaben für Ihr Projekt – z. B. für eine PostgreSQL-VM mit automatischen Backups.

centron Redaktion Technische Redaktion

Das Redaktionsteam von centron schreibt Anleitungen aus dem Betriebsalltag: getestet auf unserer eigenen Plattform, betrieben im Rechenzentrum in Hallstadt bei Bamberg.

Kategorie Java
Teilen
Noch offene Fragen?

Our team will help you with your specific setup - in German or English, by people who run the platform themselves.

War dieses Tutorial hilfreich?

Your answer is stored anonymously and helps us improve our tutorials.

Kommentare

No comments yet - be the first to ask a question about this tutorial.

Sign in to comment

Comments are open to centron customers. Sign in to your account to ask a question about this tutorial.

Weiterlesen

Das könnte Sie auch interessieren

Jetzt kostenlos anfangen

Melden Sie sich an und erhalten Sie in den ersten 60 Tagen ein Guthaben von 200 € bei centron.

Dieses Werbeangebot gilt nur für neue Konten. Angebot ausschließlich für Gewerbetreibende.

Jetzt loslegen Sales kontaktieren