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;