Hibernate
-
Upload
scrumhalf-gpe -
Category
Technology
-
view
965 -
download
3
description
Transcript of Hibernate
HibernateCriteria x HQL/JPQLFabrício PereiraProjeto Capacitar – GPEMaio/2013
Hibernate• Ferramenta ORM (Object-Relational Mapping)• Implementa a especificação JPA (Java Persistence API), e ainda
vai além fornecendo recursos adicionais• Não trata apenas do mapeamento de classes Java para tabelas
do banco de dados (e de tipos de dados Java para tipos de dados SQL), mas também oferece facilidades de consultas e recuperação de dados
2
Hibernate• Consultas polimórficas• Linguagem de consulta orientada a objeto• HQL (Hibernate Query Language)• JPQL (Java Persistence Query Language)• Criteria API• Responsabiliza-se por transformar essas consultas em SQL
nativo e recuperar o resultado de acordo com mapeamento
3
HQL / JPQL• Versão orientada a objeto do SQL• As consultas são definidas por uma string• JPQL é compatível com JPA• HQL atende a JPA, e possui mais recursos• Nem toda consulta HQL é JPQL• Toda consulta JPQL é HQL
4
Criteria API• Especificada pela JPA, e novamente o Hibernate a implementa
com mais recursos• As consultas são definidas através da instanciação de objetos
Java que representam elementos da consulta• São usadas principalmente para consultas construídas
dinamicamente, e sua estrutura completa e exata só é conhecida em tempo de execução
5
HQL / JPQL - Cláusulas• São quase as mesmas do SQL• select• from• where• order by• having• group by• insert• update• delete
6
HQL / JPQL – Agregações• avg(...)• sum(...)• min(...)• max(...)• count(*)• count(...)• count(distinct ...)• count(all...)
7
HQL / JPQL – Associações e Junções
• Explícito• inner join (join)• left outer join (left join)• right outer join (right join)• full join
• Implícito• Através da navegação (.) entre os objetos
• FETCH (força o retorno de uma propriedade lazy)• left join fetch• fetch all properties
8
HQL / JPQL – Expressões• Operadores Matemáticos• +, -, *, /
• Operações Lógicas• and, or, not
• Operadores de comparação binária• =, >, <, >=, <=, <>, !=, like
• Outros operadores• in, not in, between, is null, is not null, is empty, is not empty, member of, not member of
• Parênteses indicando agrupamento• ( )
• Case• case [...] when ... then ... else ... end
9
HQL / JPQL – Expressões• Concatenação de string• ||, concat(... , ...)
• Expressões EJB-QL 3.0• substring(), trim(), lower(), upper(), length(), locate(), abs(), sqrt(), bit_length(), mod()
• Expressões temporais• current_date(), current_time(), current_timestamp(), second(), minute(), hour(), day(), month(), year()
10
HQL / JPQL – Expressões• Conversão de tipo• str(...), cast(... as ...), extract(... from ...)
• Operações em coleções• index(), size(), minelement(), maxelement(), minindex(), maxindex(), elements(), indices()
• some, all, exists, any, in
• Parâmetros posicionados e nomeados• ?• :nomeParametro
11
HQL / JPQL – Sub-consultas• Dependente se o banco de dados suporta sub-consultas
12
HQL / JPQL – Exemplos
• String hql = “from br.ufrj.Curso”;• org.hibernate.Query q = session.createQuery(hql);• List result = q.list();
• “from Curso”; // auto-import default• “from Curso as c”• “from Curso c”• “select c from Curso c”
13
HQL / JPQL – Exemplos
• Consulta polimórfica• Experimentem !!• “from java.lang.Object o”
• Unique resultString hql = “from br.ufrj.Curso”;org.hibernate.Query q = session.createQuery(hql);
q.setMaxResult(1);Curso curso = q.uniqueResult();
14
HQL / JPQL – ExemplosSELECT cust.name, cust.address, cust.phone, cust.id, cust.current_order
FROM customers AS custJOIN cust.store_customers AS scJOIN sc.stores AS store JOIN store.locations AS locJOIN loc.product AS prod
WHERE prod.name = 'widget‘AND loc.name IN ( 'Melbourne', 'Sydney' )AND prod.id = ALL (
SELECT item.prod_idFROM line_items item, orders oWHERE item.order_id = o.id
AND cust.current_order = o.id)
15
HQL / JPQL – ExemplosSELECT order.id, SUM(price.amount), COUNT(item)FROM Order AS orderJOIN order.lineItems AS itemJOIN item.product AS product,Catalog AS catalogJOIN catalog.prices AS price
WHERE order.paid = falseAND order.customer = :customerAND price.product = productAND catalog = :currentCatalog
GROUP BY orderHAVING SUM(price.amount) > :minAmountORDER BY SUM(price.amount) DESC 16
HQL / JPQL – Exemplos
• Restrição multi-colunas através de sub-consulta
from Usuario as usr where not (usr.nome, usr.idade) in (select aluno.nome, aluno.idade from Aluno aluno)
17
HQL / JPQL – Interface Query• org.hibernate.Query• Esta interface oferece métodos para a• ligação de parâmetros• tratamento do conjunto de resultados (result set)• execução da consulta
18
HQL / JPQL – Interface Query• Regras de retorno no result set• SEM a cláusula ‘select’
• Se a cláusula ‘from’ referencia uma única classe, cada linha do result set é uma instância dessa classe
• Se a cláusula ‘from’ referencia mais de uma classe, o result set é composto por ‘Object[]’ onde cada entrada é uma instância de cada classe referenciada
19
HQL / JPQL – Interface Query• Regras de retorno no result set• COM a cláusula ‘select’
• Com um único elemento, cada linha do result set é uma instância desse elemento
• Com vários elementos, cada linha do result set é um ‘Object[]’ onde cada entrada é uma instância de cada elemento
20
HQL / JPQL – Interface Query• Parâmetros
Query q = session.createQuery("from Foo as foo where foo.name=? and foo.size=?");
q.setString(0, “test”);q.setInt(1, 5);List foos = q.list();
21
HQL / JPQL – Interface Query• Parâmetros Nomeados
Query q = session.createQuery("from Foo as foo where foo.name=:name and foo.size=:size");
q.setString(“name”, “test”);q.setInt(“size”, 5);List foos = q.list();
22
HQL / JPQL – Interface Query• Propriedades de uma entidade pode ser ligada a parâmetros
nomeados da consulta
Foo fooBean = new Foo();fooBean.setName(“test”);fooBean.setSize(5);Query q = session.createQuery("from Foo as foo where foo.name=:name and foo.size=:size");
q.setProperties(fooBean);List foos = q.list(); 23
HQL / JPQL – Interface Query• Paginação de Consultas
Query q = sess.createQuery("from DomesticCat cat");
q.setFirstResult(20);q.setMaxResults(10);List cats = q.list();
• Scroll
Query q = sess.createQuery("select cat.name, cat from DomesticCat cat " + "order by cat.name");
ScrollableResults cats = q.scroll();
24
HQL / JPQL – Interface Query
• Named Queries@Entity@NamedQuery(name=“event.moreRecentThan",
query="select e from Event e where e.date >= :date")public class Event {...
}
public class TestDao {test() {
Query q = s.getNamedQuery(“event.moreRecentThan");q.setDate("date", aMonthAgo);List results = q.list();...
}...
}
25
Criteria API – Interface Criteria• org.hibernate.Criteria• Essa interface representa uma consulta direcionada a uma
determinada classe persistente
26
Criteria API - RestriçõesCriteria cr = session.createCriteria(ClassName.class);
cr.add(Restrictions.or(criterion1, criterion2));
dis = Restrictions.disjunction();dis.add(criterion1);dis.add(criterion2);cr.add(dis);
con = Restrictions.conjunction();con.add(criterion1);con.add(criterion2);cr.add(dis);
27
Criteria API - Restrições• cr.add(Restrictions.eq());• cr.add(Restrictions.gt());• cr.add(Restrictions.ge());• cr.add(Restrictions.lt());• cr.add(Restrictions.le());• cr.add(Restrictions.like());• cr.add(Restrictions.ilike());• cr.add(Restrictions.between());• cr.add(Restrictions.isNull());• cr.add(Restrictions.isNotNull());• cr.add(Restrictions.isEmpty());• cr.add(Restrictions.isNotEmpty());
28
Criteria API – Projeções e Agregações
• cr.setProjection(Projections.rowCount());• cr.setProjection(Projections.avg());• cr.setProjection(Projections.countDistinct());• cr.setProjection(Projections.max());• cr.setProjection(Projections.min());• cr.setProjection(Projections.sum());
29
Criteria API – Ordenação e Paginação
• Ordenação• cr.addOrder(Order.asc());• cr.addOrder(Order.desc());
• Paginação• cr.setFirstResult(1);• cr.setMaxResult(10);• List result = cr.list();
• Scroll• ScrollableResults sc = cr.scroll();
30
Criteria API – Associações e Junções
• Associação• Criteria cr1 = session.createCriteria(Usuario.class);• Criteria cr2 = cr1.createCriteria(“empresa”);
• Associação com Apelido• Criteria cr = session.createCriteria(Usuario.class);• cr.createAlias(“empresa”, “emp”) 31
Criteria API – Associações e Junções
• Tipos de Junçõescriteria.createAlias("empresa", "emp", JoinType.INNER_JOIN);
criteria.createAlias("empresa", "emp", JoinType.LEFT_OUTER_JOIN);
criteria.createAlias("empresa", "emp", JoinType.RIGHT_OUTER_JOIN);
criteria.createAlias("empresa", "emp", JoinType.FULL_JOIN);
32
Criteria API – Associações e Junções
• Dependendo das junções que se faça em uma mesma consulta, é necessário incluir o código abaixo, para que não retorne resultados inesperados
• criteria.setResultTransformer( CriteriaSpecification. DISTINCT_ROOT_ENTITY);
33
Criteria API – Detached• Criteria Desacoplada da Sessãoorg.hibernate.criterion.DetachedCriteria
DetachedCriteria query = DetachedCriteria.forClass(Usuario.class)
.add( Property.forName(“perfil").eq(1) ); Session session = ....;List results =
query.getExecutableCriteria(session).list();session.close(); 34
Criteria API – Detached• Sub-consultas com DetachedCriteriaDetachedCriteria mediaNota =
DetachedCriteria.forClass(Aluno.class). setProjection(Property.forName(“nota").avg());
session.createCriteria(Cat.class).add( Property.forName(“nota").gt(mediaNota)).list();
DetachedCriteria notas =
DetachedCriteria.forClass(Aluno.class). setProjection(Property.forName(“nota“));
session.createCriteria(Aluno.class).add( Subqueries.geAll(“nota", notas)).list(); 35
Criteria API – Detached• Sub-consultas correlatas com DetachedCriteriaDetachedCriteria mediaNotaPorSexo = DetachedCriteria.forClass(Aluno.class, “aluno2“) .setProjection(Property.forName(“nota").avg()) .add(Property.forName(“aluno2.sexo").eqProperty(“aluno.sexo“));
session.createCriteria(Aluno.class, “aluno“) .add(Property.forName(“nota"). gt(mediaNotaPorSexo)).list();
36
Criteria API – Detached• Restrição multi-colunas através de sub-consultaDetachedCriteria subConsulta = DetachedCriteria.forClass( Homem.class ) .setProjection( Projections.projectionList() .add(Projections.property( “peso" )) .add(Projections.property(“altura”))) .add(Restrictions.eq(“nome", “João”));
session.createCriteria( Mulher.class ).add( Subqueries.propertiesEq( new String[] { “peso", “altura" }, subConsulta )).list();
37
Criteria API – Detached• Restrição multi-colunas através de sub-consultaDetachedCriteria subConsulta = DetachedCriteria.forClass( Homem.class ) .setProjection( Projections.projectionList() .add(Projections.property( “peso" )) .add(Projections.property(“altura”))) .add(Restrictions.eq(“nome", “João”));
session.createCriteria( Mulher.class ).add( Subqueries.propertiesEq( new String[] { “peso", “altura" }, subConsulta )).list();
38
HQL/JPQL x Criteria API - Performance
• Alguns testes comprovam que a performance para as duas linguagens é muito próxima (um pequeno ganho com HQL), mas geralmente são falhos pois não exploram todas as situações de sobrecarga
• Pode-se obter uma performance alta quando for bem utilizada cada uma das linguagens
• Mas no dia a dia dos projetos, ocorrem situações em que as duas linguagens apresentam uma grande diferença de performance para determinadas consultas em bases legadas• HQL: < 100ms• Criteria: > 15s
39
HQL/JPQL x Criteria API - Performance
• Custo da geração de SQL (em teoria)• Named HQL/JPQL Query - Geração de SQL ocorre apenas uma vez• Criteria - Sem necessidade de interpretar antes da geração• (non-named) HQL/JPQL Query - Realizar a interpretação e depois gera
• Escolher uma forma de consulta se baseando apenas nesses custo pode resultar em escolhas erradas ou inapropriadas
• Esse custo geralmente é desprezível comparado com o desempenho de um consulta diretamente em um DB
40
HQL/JPQL x Criteria API - Performance
• Pontos a considerar na escolha• Dependência com a API Hibernate (porção imcompatível com JPA)• Criteria é muito útil em consultas com parâmetros opcionais• HQL/JPQL é apropriado na maioria das consultas que são pequenas e
fáceis de entender• NamedQuery quando o custo de geração de SQL for considerável, ou ao
otimizar HQL
41
HQL/JPQL x Criteria API - Performance
• Recomenda-se que adote a medição do desempenho através de testes de carga como uma etapa natural na vida da aplicação, e assim não disponibilizar em produção apenas com micro benchmarks.
42
HQL/JPQL x Criteria API
HQL/JPQL
• Definido por string• Erros detectados em
tempo execução• Similar ao SQL• Consultas estáticas• select/insert/update/
delete• Não é tão seguro quanto
a SQL Injection• Menos custoso
Criteria API
• Definido por objetos Java• Erros detectados em
tempo compilação• Não se parece com SQL• Consultas dinâmicas• Apenas select• Seguro quanto a SQL
Injection• Mais custoso 43
HQL/JPQL x Criteria APIprivate Criteria
buildCriteriaAllFields(CampoOriginalVO campoOriginal,
MatchMode matchMode) {Criteria criteria =
getSession().createCriteria(getBeanClass());
if ((campoOriginal.getIdCampoOriginal() != null) && (!campoOriginal.getIdCampoOriginal().equals(new Long(0)))) {
criteria.add(Restrictions.idEq(campoOriginal.getIdCampoOriginal()));
}
if (campoOriginal.getOrigem() != null) {criteria.add(Restrictions.eq("origem", campoOriginal.getOrigem()));
}
if ((campoOriginal.getNomeCampo() != null) && (!campoOriginal.getNomeCampo().trim().isEmpty())) {criteria.add(Restrictions.eq("nomeCampo", campoOriginal.getNomeCampo()));
}
MetodoVO metodo = campoOriginal.getMetodo();if (metodo != null) {boolean idMetodoIsNotNull = (metodo.getIdMetodo()
!= null)&& (!metodo.getIdMetodo().equals(new Long(0)));boolean codigoMetodoIsNotNull =
(metodo.getCodigo() != null)&& (!metodo.getCodigo().trim().isEmpty());
if (idMetodoIsNotNull || codigoMetodoIsNotNull) {criteria.createAlias("metodo", "metodo");if (idMetodoIsNotNull) {criteria.add(Restrictions.eq("metodo.id", metodo.getIdMetodo()));} else if (codigoMetodoIsNotNull) {criteria.add(Restrictions.eq("metodo.codigo", metodo.getCodigo()));}
}}
criteria.addOrder(Order.asc("id"));
return criteria;}
44
HQL/JPQL x Criteria APIprivate Criteria
buildCriteriaAllFields(DPVATServiceVO vo, MatchMode matchMode) {
Criteria criteria = getSession().createCriteria(getBeanClass());
if ((vo.getChassi() != null) && (!vo.getChassi().trim().equals(""))) {
criteria.add(Restrictions.eq("cod_chas", vo.getChassi().trim().toUpperCase()));
}
if ((vo.getPlaca() != null) && (!vo.getPlaca().trim().equals(""))) {
criteria.add(Restrictions.eq("cod_placa", vo.getPlaca().trim().toUpperCase()));
}
if ((vo.getUf() != null) && (!vo.getUf().trim().equals(""))) {criteria.add(Restrictions.eq("cod_uf_dut", vo.getUf().trim().toUpperCase()));
}
if ((vo.getCpfCnpj() != null) && (!vo.getCpfCnpj().trim().equals(""))) {criteria.add(Restrictions.eq("cod_cgc_cpf", Long.parseLong(vo.getCpfCnpj().trim())));
}
criteria.addOrder(Order.desc("num_ano_exerc"));
criteria.addOrder(Order.desc("dt_proc"));criteria.addOrder(Order.desc("dt_emis_guia"));
return criteria;}
Criteria: > 15s 45
HQL/JPQL x Criteria APIprivate Query buildHqlQueryAllFields(DPVATServiceVO
vo, MatchMode matchMode) {String hqlRestrictions = "";
if ((vo.getChassi() != null) && (!vo.getChassi().trim().equals(""))) {
if (!hqlRestrictions.trim().isEmpty()) {hqlRestrictions += " and ";}hqlRestrictions += " siscon.cod_chas = '" +
vo.getChassi().trim().toUpperCase() + "' ";}
if ((vo.getPlaca() != null) && (!vo.getPlaca().trim().equals(""))) {
if (!hqlRestrictions.trim().isEmpty()) {hqlRestrictions += " and ";}hqlRestrictions += " siscon.cod_placa = '" +
vo.getPlaca().trim().toUpperCase() + "' ";}
if ((vo.getUf() != null) && (!vo.getUf().trim().equals(""))) {
if (!hqlRestrictions.trim().isEmpty()) {hqlRestrictions += " and ";}hqlRestrictions += " siscon.cod_uf_dut = '" +
vo.getUf().trim().toUpperCase() + "' ";}
if ((vo.getCpfCnpj() != null) && (!vo.getCpfCnpj().trim().equals(""))) {
if (!hqlRestrictions.trim().isEmpty()) {hqlRestrictions += " and ";}hqlRestrictions += " siscon.cod_cgc_cpf = "
+ Long.parseLong(vo.getCpfCnpj().trim()) + " ";
}
Query query = null;if (!hqlRestrictions.trim().isEmpty()) {query = getSession().createQuery("select siscon from Siscon siscon where " +
hqlRestrictions+ " order by siscon.num_ano_exerc desc,
siscon.dt_proc desc, siscon.dt_emis_guia desc");
}return query;}
HQL: < 100ms
46
HQL/JPQL x Criteria API• Se não consegue o máximo e o melhor com o SQL puro, dificilmente
irá conseguir fazer o mesmo com HQL ou Criteria!
47
Hibernate FAQ
https://community.jboss.org/en/hibernate/faq
• Performance• Dicas e Truques• Problemas Recorrentes• Problemas Avançados
48