4.1 Parametre for spørringer

Hibernate lar deg sende parametere til spørringer. Dermed er alt arbeid med spørringer og databasen betraktelig forenklet.

Det er svært sjelden å finne uforanderlige søk. Først ser det ut til at du bare trenger å returnere en liste over varer fra databasen. Og så viser det seg at du trenger en oppdatert liste over produkter for en bestemt bruker på en bestemt dato. Sortert etter det nødvendige feltet, og ikke hele listen ennå, men en bestemt side: for eksempel produkter fra 21 til 30.

Og dette er nøyaktig hva parameteriserte spørringer løser. Du skriver en spørring i HQL, og deretter erstatter du verdiene som kan endres med "spesielle navn" - parametere. Og så separat når du utfører forespørselen, kan du sende verdiene til disse parameterne.

La oss skrive en HQL-spørring som vil returnere alle oppgaver for en bruker med et spesifikt navn:

from EmployeeTask where employee.name = "Ivan Ivanovich"

La oss nå erstatte navnet med en parameter:

from EmployeeTask where employee.name = :username

Og slik vil vår Java-kode for å finne oppgaver se ut:


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

I stedet for et parameternavn kan du også bare bruke et tall:


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

Selv om det selvfølgelig er bedre å bruke navnet - er det mye lettere å lese og vedlikeholde slik kode.

4.2 setParameterList()-metoden.

Det er også tilfeller der parameterverdien ikke er én, men representerer en liste over objekter. For eksempel ønsker vi å kontrollere at yrkene til ansatte er inneholdt i en bestemt liste.

Hvordan kunne dette gjøres:


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 typer liste kan sendes som en parameterverdi:

  • rekke objekter: Objekt[]
  • samling: Samling
  • skrevet matrise: T[]
  • maskinskrevet samling: Samling<T>

Hvis du bestemmer deg for å sende en innskrevet samling eller matrise, må du sende datatypen som den tredje parameteren. Eksempel:


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

Når du arbeider med listeparametere, kan du også bruke et tall i stedet for parameternavnet. Men igjen, navnet er mer praktisk.

4.3 Beskyttelse mot SQL-injeksjon

En av de viktigste formålene med parameterne er å beskytte databasen mot SQL-injeksjoner. Mange nybegynnere programmerere, i stedet for å bruke parametere, vil ganske enkelt lime sammen en streng med flere deler.

I stedet for å skrive slik:


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

Vil skrive slik:


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

Gjør aldri det!Aldri hold sammen en SQL/HQL-spørring fra flere deler. For før eller siden vil brukernavnet komme til deg fra klienten. Og den onde hackeren vil gi deg en streng som""Ivan"; DROP TABLE user;"

Og så vil spørringen din til databasen ta formen:


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

Og det er fortsatt bra hvis dataene dine bare slettes. Du kan også skrive slik:


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

Eller slik:


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