4.1 A lekérdezések paraméterei
A hibernálás lehetővé teszi a paraméterek átadását a lekérdezéseknek. Így a lekérdezésekkel és az adatbázissal végzett munka jelentősen leegyszerűsödik.
Nagyon ritkán találni megváltoztathatatlan lekérdezéseket. Eleinte úgy tűnik, hogy csak egy árulistát kell visszaküldenie az adatbázisból. És akkor kiderül, hogy szüksége van egy naprakész terméklistára egy adott felhasználó számára egy adott napon. A kötelező mező szerint rendezve, és még nem a teljes lista, hanem egy adott oldal: például termékek 21-től 30-ig.
A paraméterezett lekérdezések pedig pontosan ezt oldják meg. Lekérdezést ír a HQL-ben, majd lecseréli a megváltoztatható értékeket „speciális nevekkel” - paraméterekkel. Ezután a kérés végrehajtásakor külön átadhatja ezen paraméterek értékeit.
Írjunk egy HQL-lekérdezést, amely egy adott nevű felhasználó összes feladatát visszaadja:
from EmployeeTask where employee.name = "Ivan Ivanovich"
Most cseréljük le a nevet egy paraméterre:
from EmployeeTask where employee.name = :username
Így fog kinézni a feladatok megtalálására szolgáló Java kódunk:
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();
A paraméter neve helyett csak egy számot is használhat:
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();
Bár természetesen jobb a név használata - sokkal könnyebb elolvasni és karbantartani az ilyen kódot.
4.2 setParameterList() metódus.
Vannak olyan esetek is, amikor a paraméter értéke nem egy, hanem objektumok listáját jelöli. Például ellenőrizni akarjuk, hogy az alkalmazottak szakmái szerepelnek-e egy bizonyos listán.
Hogyan lehetne ezt megtenni:
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 típusú lista adható át paraméterértékként:
- objektumok tömbje: Object[]
- gyűjtemény: Gyűjtemény
- beírt tömb: T[]
- gépelt gyűjtemény: Gyűjtemény<T>
Ha úgy dönt, hogy egy tipizált gyűjteményt vagy tömböt ad át, akkor harmadik paraméterként az adattípust kell átadnia. Példa:
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();
Ha listaparaméterekkel dolgozik, a paraméter neve helyett számot is használhat. De ismét a név kényelmesebb.
4.3 SQL-injekció elleni védelem
A paraméterek egyik legfontosabb célja, hogy megvédje az adatbázist az SQL injekcióktól. Sok kezdő programozó ahelyett, hogy paramétereket használna, egyszerűen több részből álló láncot ragaszt össze.
Ahelyett, hogy így írnál:
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();
így írná:
String hql = "from EmployeeTask where employee.name = " + "Ivan Ivanovich";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
List<EmployeeTask> resultLIst = query.list();
Soha ne tedd!Soha ne ragasszon össze egy SQL/HQL-lekérdezést több részből. Mert előbb-utóbb megjön a felhasználónév a klienstől. És a gonosz hacker olyan karakterláncot ad neked, mint""Ivan"; DROP TABLE user;"
Ezután az adatbázis lekérdezése a következő formában jelenik meg:
from EmployeeTask where employee.name = "Ivan"; DROP TABLE user;
És még mindig jó, ha egyszerűen törli az adatait. Írhatsz így is:
from EmployeeTask where employee.name = "Ivan";
UPDATE user SET password = '1' WHERE user.role = 'admin'
Vagy így:
from EmployeeTask where employee.name = "Ivan";
UPDATE user SET role = 'admin' WHERE user.id = 123;
GO TO FULL VERSION