4.1 Parametri pentru interogări

Hibernare vă permite să transmiteți parametri la interogări. Astfel, toate lucrează cu interogări și baza de date este mult simplificată.

Este foarte rar să găsiți interogări imuabile. La început, se pare că trebuie doar să returnați o listă de bunuri din baza de date. Și apoi se dovedește că aveți nevoie de o listă actualizată de produse pentru un anumit utilizator la o anumită dată. Sortate după câmpul obligatoriu, și nu încă întreaga listă, ci o anumită pagină: de exemplu, produse de la 21 la 30.

Și asta este exact ceea ce rezolvă interogările parametrizate. Scrieți o interogare în HQL și apoi înlocuiți valorile care pot fi modificate cu „nume speciale” - parametri. Și apoi separat atunci când executați cererea, puteți trece valorile acestor parametri.

Să scriem o interogare HQL care va returna toate sarcinile pentru un utilizator cu un nume specific:

from EmployeeTask where employee.name = "Ivan Ivanovich"

Acum să înlocuim numele cu un parametru:

from EmployeeTask where employee.name = :username

Și așa va arăta codul nostru Java pentru găsirea sarcinilor:


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();

De asemenea, în loc de numele unui parametru, puteți utiliza doar un număr:


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();

Deși este mai bine, desigur, să folosiți numele - este mult mai ușor să citiți și să mențineți un astfel de cod.

4.2 metoda setParameterList().

Există, de asemenea, cazuri când valoarea parametrului nu este una, ci reprezintă o listă de obiecte. De exemplu, vrem să verificăm dacă profesiile angajaților sunt cuprinse într-o anumită listă.

Cum se poate face acest lucru:


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();

4 tipuri de liste pot fi transmise ca valoare a parametrului:

  • matrice de obiecte: Object[]
  • colecție: Colecție
  • matrice tastata: T[]
  • colecție tipizată: Collection<T>

Dacă decideți să treceți o colecție sau o matrice tipizată, atunci trebuie să treceți tipul de date ca al treilea parametru. Exemplu:


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();

Când lucrați cu parametrii de listă, puteți utiliza și un număr în locul numelui parametrului. Dar din nou, numele este mai convenabil.

4.3 Protecție împotriva injectării SQL

Unul dintre cele mai importante scopuri ale parametrilor este protejarea bazei de date de injecțiile SQL. Mulți programatori începători, în loc să folosească parametrii, pur și simplu ar lipi împreună un șir de mai multe părți.

In loc sa scrii asa:


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();

As scrie asa:


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

Să nu faci asta niciodată!Nu lipiți niciodată o interogare SQL/HQL din mai multe părți. Pentru că mai devreme sau mai târziu numele de utilizator vă va veni de la client. Și hackerul rău vă va da un șir ca""Ivan"; DROP TABLE user;"

Și apoi interogarea ta către baza de date va lua forma:


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

Și tot e bine dacă datele tale sunt pur și simplu șterse. Puteți scrie și așa:


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

Sau cam asa:


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