4.1 Parameters voor zoekopdrachten
Met Hibernate kunt u parameters doorgeven aan query's. Zo wordt al het werk met queries en de database sterk vereenvoudigd.
Het is zeer zeldzaam om onveranderlijke zoekopdrachten te vinden. In eerste instantie lijkt het erop dat u alleen een lijst met goederen uit de database hoeft te retourneren. En dan blijkt dat je voor een bepaalde gebruiker op een bepaalde datum een actuele lijst met producten nodig hebt. Gesorteerd op het verplichte veld, en nog niet de hele lijst, maar een specifieke pagina: bijvoorbeeld producten van 21 tot 30.
En dit is precies wat geparametriseerde queries oplossen. U schrijft een query in HQL en vervolgens vervangt u de waarden die kunnen worden gewijzigd door "speciale namen" - parameters. En dan afzonderlijk bij het uitvoeren van het verzoek, kunt u de waarden van deze parameters doorgeven.
Laten we een HQL-query schrijven die alle taken retourneert voor een gebruiker met een specifieke naam:
from EmployeeTask where employee.name = "Ivan Ivanovich"
Laten we nu de naam vervangen door een parameter:
from EmployeeTask where employee.name = :username
En zo ziet onze Java-code voor het vinden van taken eruit:
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();
Ook kunt u in plaats van een parameternaam alleen een nummer gebruiken:
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();
Hoewel het natuurlijk beter is om de naam te gebruiken, is het veel gemakkelijker om dergelijke code te lezen en te onderhouden.
4.2 setParameterList() methode.
Er zijn ook gevallen waarin de parameterwaarde niet één is, maar een lijst met objecten vertegenwoordigt. We willen bijvoorbeeld controleren of de beroepen van werknemers in een bepaalde lijst voorkomen.
Hoe zou dit kunnen:
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();
Er kunnen 4 typen lijsten worden doorgegeven als parameterwaarde:
- reeks objecten: Object[]
- collectie: collectie
- getypte array: T[]
- getypte collectie: Collection<T>
Als u besluit een getypte verzameling of array door te geven, moet u het gegevenstype als derde parameter doorgeven. Voorbeeld:
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();
Wanneer u met lijstparameters werkt, kunt u ook een nummer gebruiken in plaats van de parameternaam. Maar nogmaals, de naam is handiger.
4.3 Bescherming tegen SQL-injectie
Een van de belangrijkste doelen van de parameters is om de database te beschermen tegen SQL-injecties. Veel beginnende programmeurs zouden, in plaats van parameters te gebruiken, gewoon een reeks van verschillende onderdelen aan elkaar lijmen.
In plaats van zo te schrijven:
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();
Zou zo schrijven:
String hql = "from EmployeeTask where employee.name = " + "Ivan Ivanovich";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
List<EmployeeTask> resultLIst = query.list();
Doe dat nooit!Steek nooit een SQL/HQL-query uit meerdere delen bij elkaar. Omdat vroeg of laat de gebruikersnaam van de klant naar u toekomt. En de kwaadaardige hacker geeft je een string als""Ivan"; DROP TABLE user;"
En dan zal uw vraag naar de database de vorm aannemen:
from EmployeeTask where employee.name = "Ivan"; DROP TABLE user;
En het is nog steeds goed als uw gegevens gewoon worden verwijderd. Je kunt ook zo schrijven:
from EmployeeTask where employee.name = "Ivan";
UPDATE user SET password = '1' WHERE user.role = 'admin'
Of zo:
from EmployeeTask where employee.name = "Ivan";
UPDATE user SET role = 'admin' WHERE user.id = 123;
GO TO FULL VERSION