33
1 Criando e executando consultas Formas de criar consultas

1 Criando e executando consultas Formas de criar consultas

Embed Size (px)

Citation preview

Page 1: 1 Criando e executando consultas Formas de criar consultas

1

Criando e executando consultas

Formas de criar consultas

Page 2: 1 Criando e executando consultas Formas de criar consultas

2

Formas de consultas

• Hibernate Query Language (HQL), e um subconjunto do padrão JPA QL (Java Persistence API Query Language :session.createQuery("from Category c where c.name like 'Laptop%'");

entityManager.createQuery("select c from Category c where c.name like 'Laptop%'“ );

• Criteria API para consulta por critério (QBC) e consulta por exemplo (QBE):session.createCriteria(Category.class).add( Restrictions.like("name",

"Laptop%") );

• SQL direto com ou sem mapeamento automático do resultsets para objeto.session.createSQLQuery( "select {c.*} from CATEGORY {c} where

NAME like 'Laptop%'").addEntity("c", Category.class);

Page 3: 1 Criando e executando consultas Formas de criar consultas

3

Preparando uma consulta

• As interfaces org.hibernate.Query e org.hibernate.Criteria possuem inúmeros métodos para controlar a execução de uma consulta.

• Query provê métodos para atribuir valores para parâmetros de consulta.

• Para executar uma consulta em uma aplicação é necessário obter uma instância de uma destas interfaces utilizando a Session.

Query hqlQuery = session.createQuery("from Event");

Page 4: 1 Criando e executando consultas Formas de criar consultas

4

Associação <one-to-many>

• Uma associação <um-para-muitos> liga as tabelas de duas classes através de uma chave estrangeira sem intervensão nas tabelas.

• Este mapeamento perde certa semântica para uma coleção normal Java:– Uma instância que contem uma classe entidade não pode

pertencer a mais de uma instância de coleção.– Uma instância que contem uma classe entidade não pode

aparecer em mais de um valor de um índice de coleção.

• Uma associação de Estados e Municípios requer a existência de uma coluna de chave estrangeira e a possibilidade de uma coluna índice para a tabela Municípios.

Page 5: 1 Criando e executando consultas Formas de criar consultas

5

<one-to-many class="ClassName" not-found="ignore|exception" entity-name="EntityName" node="element-name" embed-xml="true|false"/>

• class (obrigatório): O nome da classe associada• not-found (opcional): Especifica como colocar em cache

identificadores que referenciam as linhas inexistentes devem ser manipuladas. ignore tratará uma linha inexistente como uma associação nula.

• entity-name (opcional): O nome da entidade classe associada, como uma classe alternativa.

Page 6: 1 Criando e executando consultas Formas de criar consultas

6

Exemplo<hibernate-mapping> <class name="exemploestadolista.Estado"

table="Estados"> <id name="ibge" column="IBGE"> </id> <property name="sigla"/> <property name="nome"/> <property name="area"/> <set name="municipios" table="municipios"> <key column="uf"/> <one-to-many class="exemploestadolista.Municipio" /> </set> </class></hibernate-mapping>

Page 7: 1 Criando e executando consultas Formas de criar consultas

7

Limitando a quantidade de respostas

Query consulta = session.createQuery("from Estado order by sigla asc");

consulta.setMaxResults(10);

Apresenta um conjunto com 10 elementos

Page 8: 1 Criando e executando consultas Formas de criar consultas

8

Utiliza SQL e limitador

Query consulta = session.createSQLQuery("select {e.*} from estados {e} order by {e.sigla}").

addEntity("e",Estado.class);

consulta.setFirstResult(5);

consulta.setMaxResults(10);

Utiliza expressão SQL. Inicia o resultado no quinto elemento e apresenta 10 registros.

Page 9: 1 Criando e executando consultas Formas de criar consultas

9

Utiliza Criteria

Query consulta =

session

.createQuery(" from Estado order by sigla asc").setMaxResults(10);

Criteria crit =

session.createCriteria(Estado.class)

.addOrder(Order.desc("sigla"))

.setFirstResult(5)

.setMaxResults(6);

List relEstados = crit.list();

Page 10: 1 Criando e executando consultas Formas de criar consultas

10

Consulta com parâmetro

String consultaString =

"from Estado uf where uf.sigla = :pesquisa";

String ufString = "PR";

Query consulta = session.createQuery(consultaString).setString("pesquisa", ufString);

Page 11: 1 Criando e executando consultas Formas de criar consultas

11

HQL Hibernate Query Language

Caio Nakashima

[email protected]

[email protected]

Page 12: 1 Criando e executando consultas Formas de criar consultas

12

HQL

• Hibernate é equipado com uma linguagem de consulta extremamente poderosa que (intencionalmente) é muito parecida com SQL.

• HQL é completamente orientado a objetos, entendendo noções como herança, polifomorfismo e associação.

• Consultas são case-insensitive (não sensíveis à letra), com exceção de nomes para as classes e propriedades Java.

• Assim SeleCT tem o mesmo significado que sELEct e SELECT mas org.hibernate.eg.FOO não é igual a org.hibernate.eg.Foo e foo.barSet não é igual a not foo.BARSET.

Page 13: 1 Criando e executando consultas Formas de criar consultas

13

Cláusula FROM

• A mais simples consulta Hibernate é:

from eg.Cat• Que retorna todas as instâncias da classe Cat. Não

é necessário qualificar o nome da classe, desde que a auto importação é o padrão. Assim geralmente escreve-se:

from Cat• Muitas vezes, é necessário atribuir uma alias, desde

que deseja-se referir ao Cat em outras partes da consulta.

from Cat as cat

Page 14: 1 Criando e executando consultas Formas de criar consultas

14

Cláusula FROM (2)

• Esta consulta atribui para a instância Cat um alias cat, assim pode-se utiliza-lo em outras partes da expressão de consulta. A palavra chave AS é opcional, assim pode-se escrever também:

from Cat cat• Pode-se utilizar múltiplas classes, resultando um produto

cartesiano ou um "cross" join.

from Formula, Parameter

from Formula as form, Parameter as param• É considerado uma boa prática nomear alias de consulta

utilizando a primeira letra em minúscula, sendo consistente com o padrão Java para nomear variáveis locais.

Page 15: 1 Criando e executando consultas Formas de criar consultas

15

Associações e Junções

• Pode-se também associar aliases para entidades associadas ou também para elementos de uma coleção de valores utilizando JOIN.

• from Cat as cat

inner join cat.mate as mate

left outer join cat.kittens as kitten• from Cat as cat left join cat.mate.kittens as kittens

• from Formula form full join form.parameter param

Page 16: 1 Criando e executando consultas Formas de criar consultas

16

Associações e Junções

• Os tipos de junções (joins) suportados são emprestados do SQL ANSI:– inner join– left outer join– right outer join– full join

• As construções inner join, left outer join e right outer join podem ser abreviadas.

from Cat as cat

join cat.mate as mate

left join cat.kittens as kitten

Page 17: 1 Criando e executando consultas Formas de criar consultas

17

Fetching strategies

• Em um acesso tradicional aos dados, pode-se pegar todos dos dados requeridos para um processo em particular para uma consulta SQL simples, contando com a vantagem de junções internas ou externas (inner or outer joins) para recuperar as entidades relacionadas.

• Algumas primitivas implementadas no modelo ORM (object/relational mapping) para pegar "pedaços" de dados com inúmeras requisições para pequenos pedaços de dados em resposta das aplicações navegando um grafo de objetos persistentes, não é uma forma eficiente de utilização das capacidades de junção (join) do banco de dados.

Page 18: 1 Criando e executando consultas Formas de criar consultas

18

• Esta estratégia de acesso a dados é pobre por natureza.

• Uma das maiores dificuldades em ORM é prover um acesso eficiente para os dados relacionais, dando uma aplicação que prefere tratar os dados como um objeto de grafo.

• Para os tipos mais comuns de aplicações (multi-usuário, distribuído, web e aplicações coorporativas), a recuperação de objetos utilizando muitos acessos ao banco de dados não é aceitável. Será discutido que as ferramentas devem enfatizar o R em ORM para a extensão maior que a tradicional.

Page 19: 1 Criando e executando consultas Formas de criar consultas

19

• O problema de pegar objetos de grafos eficientemente, com acesso mínimo para o banco de dados, tem freqüentemente associando com o provimento ao nível de associação da estratégia de capturar um meta dados específico do mapeamento de associação.

• O problema com esta solução é que cada pedaço do código que utiliza um requisito de entidade um conjunto diferente de objetos associados. Mas isto não é suficiente.

• É necessário um suporte para refino da estratégia de execução da associação de captura.

• Hibernate suporta as duas estratégias, que permite especificar uma estratégia padrão de captura no arquivo de mapeamento e então sobre escrever em tempo de execução no código.

Page 20: 1 Criando e executando consultas Formas de criar consultas

20

• Hibernate permite escolher entre quarto estratégia de captura para qualquer associação, nos metadados de associação e em tempo de execução:

• Immediate fetching - Captura Imediata– O objeto associado é capturado imediatamente, utilizando

uma leitura em banco de dados seqüencial (cache).

• Lazy fetching - Captura preguiçosa– O objeto associado ou coleção é capturado de "forma

preguiçosa", quando é acessado. Resultada é uma nova requisição para o banco de dados (a não ser que o objeto associado esteja no cache).

Page 21: 1 Criando e executando consultas Formas de criar consultas

21

• Eager fetching - Captura urgente– Um objeto associado ou coleção é capturado junto com o

objeto proprietário, utilizando um outer join SQL, e nenhum outra requisição ao banco de dados é requerida.

• Batch fetching - Captura em Lote– Esta abordagem pode ser utilizada para melhorar a

performance da captura "preguiçosa" recuperando objetos ou coleções em lote, quando uma uma associação "preguiçosa" é acessada.

– Captura em lote pode ser utilizado para melhorar a performance da captura imediata.

Page 22: 1 Criando e executando consultas Formas de criar consultas

22

Immediate fetching (captura imediata)

• Captura associativa imediata ocorre para recuperar uma entidade do banco de dados e então recuperar imediatamente outra entidade associada ou entidades em uma requisição futura do banco de dados ou do cache.

• Captura imediata não é uma estratégia captura eficiente a não ser que espere que as entidades associadas estejam quase sempre no cache.

Page 23: 1 Criando e executando consultas Formas de criar consultas

23

Lazy fetching (captura preguiçosa)

• Quando um cliente requisita uma entidade e seu grafo de objetos associdado do banco de dados, não é usualmente necessário recuperar todo o grafo de todos os objetos associados (indiretamente).

• Não se deseja carregar todo o banco de dados para a memória de uma vez, por exemplo, carregar um Pedido simples, não deve disparar uma carga de todos os itens do pedido.

• Lazy fetching permite ao programador decidir quantos grafos de objetos serão carregados no primeiro acesso ao banco de dados e quais associações devem ser carregadas somente quando forem acessadas pela primeira vez.

Page 24: 1 Criando e executando consultas Formas de criar consultas

24

Lazy fetching (cont.)

• Lazy fetching é um conceito fundamental em persistência de objetos e o primeiro passo para obter uma performance aceitável.

• Recomenda-se que, para começar com todas as associações sejam configurados para lazy ou talvez para batched lazy carregamento no arquivo de mapeamento.

• Esta estratégia pode ser carregada (definida) em tempo de execução por consultas que forçam uma carga urgente.

Page 25: 1 Criando e executando consultas Formas de criar consultas

25

Eager (outer join) fetching

• Carga associada preguiçosa pode ajudar a reduzir a carga no banco de dados e é geralmente uma boa estratégia padrão.

• Porém, é algo parecido como um "chute no escuro" assim como uma otimização de performance.

• Carga urgente permite explicitamente especificar qual objeto associado deve ser carregado junto com o objeto referenciado.

• Hibernate pode então retornar o objeto associado em uma requisição simples no banco de dados, utilizando um SQL OUTER JOIN.

Page 26: 1 Criando e executando consultas Formas de criar consultas

26

Eager (outer join) fetching

• Otimização de performance no Hibernate geralmente envolve um uso discreto da carga urgente para uma transação em particular.

• Desta forma, mesmo que padrão a carga urgente pode ser declarada no arquivo de mapeamento, é mais comum para uma utilização específica desta estratégia em tempo de execução para uma HQL particular ou critério de consulta.

Page 27: 1 Criando e executando consultas Formas de criar consultas

27

Batch fetching

• Carga em lote não é estritamente uma estratégia de carga associada; é uma técnica que pode ajudar a melhorar a performance da carga preguiçosa ou carga imediata.

• Geralmente, quando se carrega um objeto ou uma coleção, a cláusula WHERE do SQL especifica o identificador do objeto ou os objetos que possuem a coleção.

• Se a carga em lote estiver habilitada, Hibernate procura ver o que outras instâncias de proxie ou coleções não inicializadas são referenciadas na seção corrente e tenta carrega-los ao mesmo tempo especificando múltiplos valores identificadores na clásula WHERE.

Page 28: 1 Criando e executando consultas Formas de criar consultas

28

• Carga urgente é geralmente mais rápida.• Carga em batch é mais fácila para os usuários

inexperientes que desejam arquivar com uma performance aceitável com Hibernate sem ter que pensar muito sobre o que SQL executará.

Page 29: 1 Criando e executando consultas Formas de criar consultas

29

Selecionando uma estratégia de carga no mapeamento

• Hibernate permite selecionar associação padrão para estratégia de carga especificando atributos nos metadados de mapeamento.

• Pode-se carregar uma estratégia padrão utilizando características de consulta do Hibernate.

• A wrinkle in Hibernate’s mapping format means that collection mappings function slightly differently than single-point associations; so, we’ll cover the two cases separately.

• Let’s first consider both ends of the bidirectional association between Bid and Item.

Page 30: 1 Criando e executando consultas Formas de criar consultas

30

• Uma junção "fetch" permite associações ou coleções de valores serem inicializadas por seus objetos pai, utilizando uma seleção simples.

• É útil particularmente em caso de uma coleção (collection).

• É eficiente para sobre escrever um outer join e lazy declarations do arquivo de mapeamento para associações e coleções.

from Cat as cat

inner join fetch cat.mate

left join fetch cat.kittens

Page 31: 1 Criando e executando consultas Formas de criar consultas

31

• Um fetch join geralmente não necessita atribuir um alias, por que os objetos associados não deve ser utilizado na cláusula where ou qualquer outra cláusula.

• Objetos associados não retornam diretamente em resultados de uma consulta.

• Por outro lado, podem ser acessados por objetos pai.

• A única razão que se necessita um alias se existir um join fetching recursivo para uma coleção futura.

Page 32: 1 Criando e executando consultas Formas de criar consultas

32

from Cat as cat

inner join fetch cat.mate

left join fetch cat.kittens child

left join fetch child.kittens• Prestar atenção que uma construção com fetch não

deve ser utilizado com consultas chamadas utilizando scroll() ou iterate().

• Nem o fetch pode ser utilizado junto com setMaxResults() ou setFirstResult().

Page 33: 1 Criando e executando consultas Formas de criar consultas

33

Produto Cartesiano

• É possível criar um produto cartesiano juntando mais de uma coleção de em uma consulta, assim deve-se tomar cuidado neste caso.– Juntando múltiplas coleções pode resultar em resultados

inesperados de um mapeamento mal feito.

• Se utilizar a propriedade lazy fetching com a instrumentalização bytecode, é possível forçar o Hibernate a percorrer a propriedade lazy imediatamente na primeira consulta utilizando todas as propriedades de navegação.

from Document fetch all properties order by name

from Document doc fetch all properties where lower(doc.name) like '%cats%'