4.1 查詢參數
Hibernate 允許您將參數傳遞給查詢。因此,所有與查詢和數據庫的工作都大大簡化了。
很難找到不可變的查詢。起初,您似乎只需要從數據庫中返回一個商品列表即可。然後事實證明,您需要在特定日期為特定用戶提供最新的產品列表。按必填字段排序,但不是整個列表,而是特定頁面:例如,從 21 到 30 的產品。
而這正是參數化查詢解決的問題。你用 HQL 寫一個查詢,然後你用“特殊名稱”——參數來替換可以改變的值。然後分別在執行請求的時候,可以傳遞這些參數的值。
讓我們編寫一個 HQL 查詢,它將返回具有特定名稱的用戶的所有任務:
from EmployeeTask where employee.name = "Ivan Ivanovich"
現在讓我們用參數替換名稱:
from EmployeeTask where employee.name = :username
這就是我們用於查找任務的 Java 代碼的樣子:
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 = :1";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
query.setParameter(1, "Ivan Ivanovich");
List<EmployeeTask> resultLIst = query.list();
當然,使用名稱當然更好 - 閱讀和維護此類代碼要容易得多。
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種類型的列表可以作為參數值傳遞:
- 對像數組:Object[]
- 收藏:收藏
- 類型數組:T[]
- 類型集合:Collection<T>
如果您決定傳遞類型化集合或數組,則需要將數據類型作為第三個參數傳遞。例子:
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();
使用列表參數時,您還可以使用數字代替參數名稱。但同樣,名稱更方便。
4.3 防止SQL注入
這些參數最重要的目的之一是保護數據庫免受 SQL 注入。許多新手程序員不使用參數,而是簡單地將幾個部分的字符串粘合在一起。
而不是這樣寫:
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 查詢粘在一起。因為用戶名遲早會從客戶端傳給你。邪惡的黑客會給你一個字符串""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