帶參數的請求

開放

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;
留言
  • 受歡迎
你必須登入才能留言
此頁面尚無留言