4.1 Parâmetros para consultas
O Hibernate permite que você passe parâmetros para consultas. Assim, todo trabalho com consultas e o banco de dados fica bastante simplificado.
É muito raro encontrar consultas imutáveis. A princípio, parece que você só precisa retornar uma lista de mercadorias do banco de dados. E então você precisa de uma lista atualizada de produtos para um usuário específico em uma data específica. Ordenado pelo campo obrigatório, e ainda não por toda a lista, mas por uma página específica: por exemplo, produtos de 21 a 30.
E é exatamente isso que as consultas parametrizadas resolvem. Você escreve uma consulta em HQL e substitui os valores que podem ser alterados por "nomes especiais" - parâmetros. E então separadamente ao executar a solicitação, você pode passar os valores desses parâmetros.
Vamos escrever uma consulta HQL que retornará todas as tarefas para um usuário com um nome específico:
from EmployeeTask where employee.name = "Ivan Ivanovich"
Agora vamos substituir o nome por um parâmetro:
from EmployeeTask where employee.name = :username
E é assim que nosso código Java para encontrar tarefas ficará:
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();
Além disso, em vez de um nome de parâmetro, você pode usar apenas um número:
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();
Embora seja melhor, é claro, usar o nome - é muito mais fácil ler e manter esse código.
4.2 Método setParameterList().
Também existem casos em que o valor do parâmetro não é um, mas representa uma lista de objetos. Por exemplo, queremos verificar se as profissões dos funcionários estão contidas em uma determinada lista.
Como isso poderia ser feito:
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 tipos de lista podem ser passados como um valor de parâmetro:
- array de objetos: Object[]
- coleção: coleção
- matriz digitada: T[]
- coleção digitada: Collection<T>
Se você decidir passar uma coleção ou array digitado, precisará passar o tipo de dados como o terceiro parâmetro. Exemplo:
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();
Ao trabalhar com parâmetros de lista, você também pode usar um número em vez do nome do parâmetro. Mas, novamente, o nome é mais conveniente.
4.3 Proteção contra SQL Injection
Um dos propósitos mais importantes dos parâmetros é proteger o banco de dados de injeções de SQL. Muitos programadores iniciantes, em vez de usar parâmetros, simplesmente colariam uma sequência de várias partes.
Em vez de escrever assim:
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();
Escreveria assim:
String hql = "from EmployeeTask where employee.name = " + "Ivan Ivanovich";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
List<EmployeeTask> resultLIst = query.list();
Nunca faça isso!Nunca junte uma consulta SQL/HQL de várias partes. Porque, mais cedo ou mais tarde, o nome de usuário chegará até você do cliente. E o hacker do mal lhe dará uma string como""Ivan"; DROP TABLE user;"
E então sua consulta ao banco de dados terá o seguinte formato:
from EmployeeTask where employee.name = "Ivan"; DROP TABLE user;
E ainda é bom se seus dados forem simplesmente excluídos. Você também pode escrever assim:
from EmployeeTask where employee.name = "Ivan";
UPDATE user SET password = '1' WHERE user.role = 'admin'
Ou assim:
from EmployeeTask where employee.name = "Ivan";
UPDATE user SET role = 'admin' WHERE user.id = 123;
GO TO FULL VERSION