4.1 Parameter für Anfragen

Mit Hibernate können Sie Parameter an Abfragen übergeben. Dadurch wird die gesamte Arbeit mit Abfragen und der Datenbank erheblich vereinfacht.

Es ist sehr selten, unveränderliche Abfragen zu finden. Auf den ersten Blick scheint es so, als müssten Sie lediglich eine Warenliste aus der Datenbank zurückgeben. Und dann stellt sich heraus, dass Sie eine aktuelle Produktliste für einen bestimmten Benutzer zu einem bestimmten Datum benötigen. Sortiert nach dem Pflichtfeld und noch nicht der gesamten Liste, sondern einer bestimmten Seite: zum Beispiel Produkte von 21 bis 30.

Und genau das lösen parametrisierte Abfragen. Sie schreiben eine Abfrage in HQL und ersetzen dann die änderbaren Werte durch „spezielle Namen“ – Parameter. Und dann können Sie beim Ausführen der Anfrage separat die Werte dieser Parameter übergeben.

Schreiben wir eine HQL-Abfrage, die alle Aufgaben für einen Benutzer mit einem bestimmten Namen zurückgibt:

from EmployeeTask where employee.name = "Ivan Ivanovich"

Ersetzen wir nun den Namen durch einen Parameter:

from EmployeeTask where employee.name = :username

Und so sieht unser Java-Code zum Finden von Aufgaben aus:


String hql = "from EmployeeTask where employee.name = :username";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
query.setParameter("username", "Ivan Ivanovich");
List<EmployeeTask> resultLIst = query.list();

Anstelle eines Parameternamens können Sie auch nur eine Zahl verwenden:


String hql = "from EmployeeTask where employee.name = :1";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
query.setParameter(1, "Ivan Ivanovich");
List<EmployeeTask> resultLIst = query.list();

Obwohl es natürlich besser ist, den Namen zu verwenden, ist es viel einfacher, solchen Code zu lesen und zu verwalten.

4.2 setParameterList()-Methode.

Es gibt auch Fälle, in denen der Parameterwert nicht eins ist, sondern eine Liste von Objekten darstellt. Wir wollen beispielsweise prüfen, ob die Berufe der Mitarbeiter in einer bestimmten Liste enthalten sind.

Wie könnte das gemacht werden:


String hql = "from EmployeeTask where occupation IN (:occupation_list)";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
query.setParameterList("occupation_list", new String[] {"Programmer", "Tester"});
List<EmployeeTask> resultLIst = query.list();

Als Parameterwert können 4 Listentypen übergeben werden:

  • Array von Objekten: Object[]
  • Sammlung: Sammlung
  • typisiertes Array: T[]
  • typisierte Sammlung: Collection<T>

Wenn Sie sich für die Übergabe einer typisierten Sammlung oder eines Arrays entscheiden, müssen Sie den Datentyp als dritten Parameter übergeben. Beispiel:


String hql = "from EmployeeTask where occupation IN (:occupation_list)";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
query.setParameterList("occupation_list", new String[] {"Programmer", "Tester"}, String.class);
List<EmployeeTask> resultLIst = query.list();

Beim Arbeiten mit Listenparametern können Sie anstelle des Parameternamens auch eine Zahl verwenden. Aber auch hier ist der Name bequemer.

4.3 Schutz vor SQL-Injection

Einer der wichtigsten Zwecke der Parameter besteht darin, die Datenbank vor SQL-Injections zu schützen. Viele unerfahrene Programmierer würden, anstatt Parameter zu verwenden, einfach eine Reihe mehrerer Teile zusammenkleben.

Anstatt so zu schreiben:


String hql = "from EmployeeTask where employee.name = :username";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
query.setParameter("username", "Ivan Ivanovich");
List<EmployeeTask> resultLIst = query.list();

Würde so schreiben:


String hql = "from EmployeeTask where employee.name = " + "Ivan Ivanovich";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
List<EmployeeTask> resultLIst = query.list();

TU das niemals!Setzen Sie eine SQL/HQL-Abfrage niemals aus mehreren Teilen zusammen. Denn früher oder später wird Ihnen der Benutzername vom Client übermittelt. Und der böse Hacker wird Ihnen eine Zeichenfolge geben""Ivan"; DROP TABLE user;"

Und dann nimmt Ihre Anfrage an die Datenbank die Form an:


from EmployeeTask where employee.name = "Ivan"; DROP TABLE user;

Und es ist trotzdem gut, wenn Ihre Daten einfach gelöscht werden. Sie können auch so schreiben:


from EmployeeTask where employee.name = "Ivan";
UPDATE user SET password = '1' WHERE user.role = 'admin'

Oder so:


from EmployeeTask where employee.name = "Ivan";
UPDATE user SET role = 'admin' WHERE user.id = 123;