4.1 Параметри за заявки
Hibernate ви позволява да предавате параметри на заявки. По този начин цялата работа със заявките и базата данни е значително опростена.
Много рядко се намират неизменни заявки. Първоначално изглежда, че просто трябва да върнете списък със стоки от базата данни. И тогава се оказва, че имате нужда от актуален списък с продукти за конкретен потребител на определена дата. Сортирани по задължителното поле и все още не целия списък, а конкретна page: например продукти от 21 до 30.
И точно това решават параметризираните заявки. Пишете заявка в HQL и след това замествате стойностите, които могат да се променят със „специални имена“ - параметри. И след това отделно, когато изпълнявате заявката, можете да предадете стойностите на тези параметри.
Нека напишем HQL заявка, която ще върне всички задачи за потребител с конкретно име:
from EmployeeTask where employee.name = "Ivan Ivanovich"
Сега нека заменим името с параметър:
from EmployeeTask where employee.name = :username
Ето How ще изглежда нашият Java code за намиране на задачи:
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();
Също така, instead of име на параметър, можете да използвате само число:
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();
Въпреки че е по-добре, разбира се, да използвате името - много по-лесно е да четете и поддържате такъв code.
4.2 метод setParameterList().
Има и случаи, когато стойността на параметъра не е една, а представлява списък от обекти. Например, искаме да проверим дали професиите на служителите се съдържат в определен списък.
Как може да стане това:
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[]
- въведена колекция: Collection<T>
Ако решите да предадете въведена колекция or масив, тогава трябва да предадете типа данни като трети параметър. Пример:
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();
Когато работите с параметри на списък, можете също да използвате число instead of името на параметъра. Но пак името е по-удобно.
4.3 Защита срещу SQL инжектиране
Една от най-важните цели на параметрите е да защити базата данни от SQL инжекции. Много начинаещи програмисти, instead of да използват параметри, просто биха слепor низ от няколко части.
Вместо да пишеш така:
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();
Бих написал така:
String hql = "from EmployeeTask where employee.name = " + "Ivan Ivanovich";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
List<EmployeeTask> resultLIst = query.list();
Никога не правете това!Никога не свързвайте SQL/HQL заявка от няколко части. Защото рано or късно потребителското име ще дойде при вас от клиента. И злият хакер ще ви даде низ като""Ivan"; DROP TABLE user;"
И тогава вашата заявка към базата данни ще приеме формата:
from EmployeeTask where employee.name = "Ivan"; DROP TABLE user;
И пак е добре данните ви просто да бъдат изтрити. Можете също да напишете така:
from EmployeeTask where employee.name = "Ivan";
UPDATE user SET password = '1' WHERE user.role = 'admin'
Или така:
from EmployeeTask where employee.name = "Ivan";
UPDATE user SET role = 'admin' WHERE user.id = 123;
GO TO FULL VERSION