带参数的请求

可用

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;
评论
  • 受欢迎
你必须先登录才能发表评论
此页面还没有任何评论