Hibernate: Consultas
Francisco do Nascimento
PSC - Programação de Softwares
Corporativos
UNIBRATEC, outubro de 2008
Consultas
Umas das partes mais interessantes do acesso a
dados
Consultas complexas podem levar um bom tempo
para serem escritas e podem ter considerável impacto
na performance da aplicação
Consultas são escritas utilizando conceitos de
orientação a objetos
Objetos no lugar de tabelas
Propriedades no lugar de colunas
Experiência em SQL não é desprezada
2
Consultas
Podem ser feitas de três maneiras
Hibernate Query Language (HQL)
Criteria API e Query by Example
Utilizando SQL
3
Consultas: Exemplos
// Através de HQL
session.createQuery("from Category c where c.name like 'Laptop%'");
// Utilizando-se Criteria
session.createCriteria(Category.class).add(
Restrictions.like("name", "Laptop%"));
// Através de SQL
session.createSQLQuery(
"select * from cad.CATEGORY where name_category like
'Laptop%'");
4
Consultas
Envolve alguns passos
Criar a consulta com as restrições necessárias
Adicionar parâmetros à consulta
Executar a consulta e recuperar o resultado
A forma de execução da consulta e obtenção dos dados
pode ser configurada
5
Criando a Consulta
Objetos Query e Criteria são obtidos através
do Session
org.hibernate.Query
org.hibernate.Criteria
Query query = session.createQuery("from User");
Criteria criteria = session.createCriteria(User.class);
6
Adicionando Parâmetros à Consulta
Parâmetros não devem ser adicionados na
própria String da consulta
"from Item i where i.description like '" + search +
"'"
Parâmetros podem ser adicionados através
de sua posição ou de seu nome
7
Adicionando Parâmetros pelo Nome
Nome do parâmetro é precedido de “:”
O valores são adicionados através de
métodos sets
String queryString = "from Item item where item.description like
:search";
Query q = session.createQuery(queryString).setString("search",
searchString);
String queryString = "from Item item"
+ " where item.description like :search"
+ " and item.date > :minDate";
Query q = session.createQuery(queryString).setString("search",
searchString).setDate("minDate", mDate);
8
Adicionando Parâmetros pela Posição
A consulta contém “?” para indicar a
existência de alguma parâmetro
Os valores também são adicionado através
de métodos sets
String queryString = "from Item item"
+ " where item.description like ?" + " and item.date > ?";
Query q = session.createQuery(queryString).setString(0,
searchString).setDate(1, minDate);
9
Executando a Consulta
Se mais de um objeto pode ser retornado,
chama-se o método list()
List list = query.list();
Se somente um objeto pode ser retornado,
chama-se o método uniqueResult()
User user = (User) query.uniqueResult();
O método retorna null se nenhum objeto for
encontrado
Se a consulta retornar mais de um objetos, a
exceção NonUniqueResultException é lançada
10
Executando a Consulta
Query query = session.createQuery("from User");
List<User> list = query.list();
for (User user : list) {
System.out.println(user.getName());
}
Query query2 = session.createQuery(
"from User user where user.name =:name").setString("name",
"SUNSP");
User user = (User) query2.uniqueResult();
System.out.println(user.getName());
11
Consultas Básicas
A consulta mais simples tem somente a
cláusula FROM
“from Item”
Para se referenciar as propriedades de uma
entidade, um ALIAS deve ser criado
“from Item as item”
“from Item item”
Palavra chave “as” é opcional
A consulta não é case-sensitive
“FROM Item AS item” também pode ser utilizada
12
Consultas Polimórficas
Consultas podem ser escritas utilizando
polimorfismo
“from Pessoa”
Retorna todas as entidades que herdam de
Pessoa
Aluno
 Professor
13
Restrições
Geralmente não se quer trazer todo o
conteúdo da tabela
Restrições devem ser adicionadas para
restringir os objetos retornados
HQL também utiliza-se a cláusula WHERE
As restrições são feitas sobre propriedades
da entidade
14
Restrições
Literais e condições podem ser incluídos
Utiliza-se aspas simples para literais do tipo String
“from Usuario u where u.email = '[email protected]'”
“from Item i where i.ativo = true”
Comparações podem ser realizadas
“from Produto p where p.quantidade between 1 and 10”
“from Produto p where p.quantidade > 100”
“from Usuario u where u.email in ('foo@bar', 'bar@foo')”
15
Comparações
Operador LIKE pode ser utilizado
“%” representa qualquer seqüência de caracteres
_ (Under_Score) representa qualquer caractere
“from Usuario u where u.nome like 'G%'”
Negação pode ser utilizada
“from Usuario u where u.nome not like '%Foo B%'”
Operadores lógicos e parênteses
“from Usuario user where user.nome like 'G%'
and user.sobrenome like 'K%'”
16
Comparações
Operadores lógicos e parênteses
“from Usuario u where (u.nome like 'G%' and
u.sobrenome like 'K%' ) or u.email in
('[email protected]', '[email protected]' )”
Coleções
"from Venda d where d.itens is not empty"
17
Comparações
Funções podem ser chamadas a partir do HQL
HQL permite a chamada de funções SQL na cláusula
WHERE
Funções podem ser definidas pelo usuário
Funções UPPER() e LOWER()
"from Usuario u where lower(u.email) =
'[email protected]'"
Função SIZE()
Depende do suporte do banco de dados
from Venda v where size(v.itens) > 3
E muitas outras...
18
Comparações
Outras funções
CONCAT(s1, s2)
SUBSTRING(s, offset, length)
TRIM( [[BOTH|LEADING|TRAILING] s)
Offset começa a partir de 1
"from Item i where TRIM(BOTH i.name) = 'Computador'"
LENGTH(s)
LOCATE(search, s, offset)
Procura a localização de uma substring dentro de uma
string
19
Comparações
Outras funções
CURRENT_DATE(), CURRENT_TIME(),
CURRENT_TIMESTAMP()
Valores retornados são referentes ao SGBD
SECOND(d), MINUTE(d), HOUR(d), DAY(d),
MONTH(d), YEAR(d)
Extraem os valores de um argumento temporal
20
Ordenando o Resultado
A Cláusula ORDER BY é utilizada para ordenar o
resultado
Ordem ascendente ou descendente
"from Usuario u order by u.nome"
Utiliza-se asc ou desc
from Usuario u order by u.login desc
Ordenando por mais de uma propriedade
“from Usuario u order by u.sobrenome asc, u.nome asc”
21
Junções
A habilidade de realizar junções é uma das
principais forças do modelo relacional
Permite selecionar diferentes objetos
associados e coleções em uma única
consulta
22
Inner Join
Contém somente os registros que estão
relacionados com o outro lado da junção
Contém somente os Itens que possuem Bids
23
(left) Outer Join
Retorna todos os Itens
Dados de Bid são preenchidos com NULL se não
houver uma correspondência
24
Junção com HQL
Coluna de junção não precisar ser informada na
consulta
É necessário ser informado somente o nome da
associação
Informação é extraída do mapeamento
Nome do atributo que referencia a classe ou coleção de
classes
Joins podem ser executados de duas maneiras
Join implícitos na Associação
Join especificado na cláusula FROM
25
Join Implícito na Associação
O Join é realizado através da associação entre duas
entidades
Exemplo:
“from Bid bid where bid.item.description like '%Foo%'”
Bid é associado a Item através do atributo “item”
Hibernate sabe que a associação está mapeada a partir
da chave estrangeira ITEM_ID da tabela BID
Joins implícitos são sempre realizados através de
associações many-to-one ou one-to-one
26
Join Implícito na Associação
Múltiplos joins são possíveis
from Bid bid where bid.item.category.name like
'Laptop%'
27
Join especificado na Cláusula FROM
Joins podem ser especificados explicitamente na
cláusula FROM
Exemplo
"select i from Item i join i.bids b where b.amount > 10"
Aliases devem ser especificados na cláusula FROM
e utilizados na cláusula WHERE
Cláusula SELECT é utilizada para que somente
Itens sejam retornados
28
Join especificado na Cláusula FROM
Na consulta, um Item pode ser retornado
mais de uma vez
Uma para cada Bid associado
Somente uma instância é utilizada
A consulta possui o mesmo formato para
associações many-to-one e one-to-one
29
Outer Joins
Para a utilização de Outer Joins utiliza-se a cláusula
LEFT JOIN
LEFT OUTER JOIN e RIGHT OUTER JOIN também
podem ser utilizados
A cláusula WITH é utilizada para adicionar restrições
"select i from Item i left join i.bids b with b.amount >=
9"
Itens que não possuem Bids também são retornados
30
Comparando Identificadores
Entidades também podem ser adicionadas
como parâmetros de uma consulta
Query query = session.createQuery("from Item i where
i.seller = :seller");
query.setEntity("seller", user);
31
HQL
Consultas não precisam aparecer no código
 Na verdade, muitas vezes é melhor que não apareçam
 Podem ficar nos metadados e serem chamadas pelo nome
Usa-se o método getNamedQuery()
List clientes =
session.getNamedQuery(“findClienteByName”)
.setString(“nome”, nome),list()
Mas antes, ela precisa ser declarada em algum arquivo de
mapeamento ou anotada em alguma entidade
<query name=“findClienteByName”><![CDATA[
from Cliente c where c.nome like :nome]]
</query>
NamedQueries com Annotation
package auction.model;
import ...;
@NamedQueries({
@NamedQuery(
name = "findItemsByDescription",
query = "select i from Item i where i.description like :desc"
),
...
})
@Entity
@Table(name = "ITEM")
public class Item { ... }
Paginando o resultado
Query query =
session.createQuery("from User u order by u.name asc");
query.setFirstResult(5);
query.setMaxResults(10);
Instanciação dinâmica
select new Aluno(
a.id, a.nome, a.idade, a.curso
)
from Aluno a
where a.curso is not null
group by a.nome