Hibernate Java avançado – PCC Jobson Ronan {[email protected]} Guilherme Kelly {[email protected]}

51
Hibernate Java avançado – PCC Jobson Ronan {[email protected]} Guilherme Kelly {[email protected]}

Transcript of Hibernate Java avançado – PCC Jobson Ronan {[email protected]} Guilherme Kelly {[email protected]}

Page 1: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Hibernate

Java avançado – PCCJobson Ronan {[email protected]}

Guilherme Kelly {[email protected]}

Page 2: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

O que é?

Hibernate é uma moderna solução de mapeamento objeto-realcional(ORM) Persistência tranparente (POJO/Java

Beans) “Lazy Fetching” Uso de uma Cache Três estratégias para o mapeamento de

heranças

Page 3: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

O que é?

Page 4: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Pra que transparência?

Persistência sem impacto no código dos objetos de negócio

Qualquer classe pode ser uma classe persistente sem ser necessário implementar nenhuma classe ou interface

Classes persistentes podem ser usadas fora do contexto de persistência (ex Testes)

Total portabilidade sem dependências

Page 5: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Problemas dos BDRs

Modelagem Não há polimorfismo Não há herança

Lógica de negócio Stored procedures -> perca de

portabilidade

Page 6: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Vantagens dos RDBs

Trabalhar com grandes quantidades de dados Busca, ordenação

Trabalhar com conjuntos de dados Junções e agregações

Compartilhamento Concorrência (Transações) Muitas aplicações

Integridade Restrições (Constraints) Isolação de transações

Page 7: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Obviamente, ainda precisamos dos RDBs

Page 8: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Objetivo

Aproveitar-se das vantagens oferecidas pelos RDBs

Isso sem perder a orientação a objetos

Page 9: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Objetivo Real

Ter menos trabalho Ter um DBA feliz

Page 10: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Em prática

Locadora em partes...

Page 11: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Em prática

Classe Persistente Construtor default Pares de Get´s e

Set´s Uma propriedade

identificadora

package br.org.citi.pec.locadora;

public class Filme { private int codigo; private String nome; public int getCodigo() { return codigo; }

private void setCodigo(int codigo) { this.codigo = codigo; }

public String getNome() { return nome; }

private void setNome(int nome) { this.nome = nome; }}

Page 12: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Em prática

Mapeamento XML Metadado legível Mapeamento de tabelas e colunas<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping> <class name="br.org.citi.pec.locadora.Filme" table="filmes"> <id name="codigo" column="filme_id"> <generator class="native" /> </id>

<property name="nome" column="nome"/>

</class></hibernate-mapping>

Page 13: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Em prática

Salvando um objeto

Session session = sessionFactory.openSession();

Transaction tx = s.beginTransaction();

Filme filme = new Filme();

filme.setNome(novoNome);

session.save(filme);

tx.commit();

session.close();

Também pode ser usado saveOrUpdate

Page 14: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Em prática

Carregando um objeto

Session session = sessionFactory.openSession();

Filme filme = (Filme) session.load(Filme.class,

new Integer(filmeId);

session.close();

Não use load para determinar se um objeto existe (uma exceção é lançada neste caso)

Use get. Este retorna null caso o objeto não exista

Page 15: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Em prática

Removendo um objeto

Session session = sessionFactory.openSession();

Transaction tx = s.beginTransaction();

Filme filme = (Filme) session.get(Filme.class,

new Integer(filmeId);

session.delete(filme);

tx.commit();

session.close();

Page 16: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Em prática

Atualizando um objeto (Dirty Checking) Obetendo um filme e alterando seu nome

Session session = sessionFactory.openSession();

Transaction tx = s.beginTransaction();

Filme filme = (Filme) session.get(Filme.class,

new Integer(filmeId);

filme.setNome(novoNome);

tx.commit();

session.close();

Não é necessário uma chamada explicita do update

Page 17: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Estado dos Objetos

Alguns conceitos sobre objetos Transiente.

• Nunca persistido. Não associado a nenhuma sessão (Session)

Persistente

• Associado a uma única sessão

Desacoplado (Detached)

• Já persistido, mas não associado a nenhuma sessão

Page 18: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Estado dos Objetos

Dirty Checking só funciona em objetos persistentes Use update para objetos desacoplados

Page 19: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Mais prática

Melhorando nosso modelo...

Page 20: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Mais prática Classes persistentes

package br.org.citi.pec.locadora;

public class Cliente { private String login; private String CPF; private String nome; private Set locacoes = new Hashset();

//... Get´s e Set´s}

Page 21: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Mais prática

package br.org.citi.pec.locadora;

public class Locacao { private int id;

private Filme filme; private Cliente cliente;

private Date dataLocacao; private Date datadevolucao;

//... Get´s e Set´s}

Classes persistentes

Page 22: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Mais prática XML...

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping> <class name="br.org.citi.pec.locadora.Cliente" table="Clientes"> <id name="login"/>

<property name="nome" /> <property name="cpf" />

<set name="locacoes"> <key column="cliente_login" /> <one-to-many class="br.org.citi.pec.locadora.Locacao"/> </set> </class></hibernate-mapping>

Page 23: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Mais prática

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping> <class name="br.org.citi.pec.locadora.Locacao" table="Locacoes"> <id name="id"> <generator class="native" /> </id>

<property name="dataLocacao" /> <property name="dataDevolucao" />

<many-to-one name="cliente" class="br.org.citi.pec.locadora.Cliente" column="cliente_login"/> <many-to-one name="filme" class="br.org.citi.pec.locadora.Filme" column="filme_id"/> </class></hibernate-mapping>

XML...

Page 24: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Mais prática Persistência transitiva

Locacao locacao = new Locacao();

Locacao.setDataLocacao(new Date());

Session session = sessionFactory.openSession();

Transaction tx = s.beginTransaction();

Filme filme = (Filme)

session.get(Filme.class, new Integer(filmeId);

Cliente cliente = (Cliente)

session.get(Cliente.class, login);

locacao.setCliente(cliente);

locacao.setFilme(filme);

cliente.getLocacoes().add(locacao);

tx.commit();

session.close();

Page 25: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Otimizando

Como as coleções são carregadas Lazy fetching (Default) Eager (Outer Join) fetching

• Indicado nos XML, ou na própria consulta

Page 26: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Lazy fetching

Cliente cliente = (Cliente) session.get(Cliente.class, login);

SELECT … FROM CLIENTES C WHERE C.LOGIN = ?

Iterator cliente = cliente.getLocacoes().iterate();

SELECT … FROM LOCACOES L WHERE L.LOGIN_CLIENTE = ?

Filme filme = locacao.getFilme();

SELECT … FROM FILMES F WHERE F.FILME_ID = ?

SQL escondido:

Page 27: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Outer join fetching SQL escondido:

Cliente cliente = (Cliente) session.get(Cliente.class, login);

SELECT … FROM CLIENTES CLEFT OUTER JOIN LOCACOES L ON L.LOGIN_CLIENTE = C.LOGIN

LEFT OUTER JOIN FILME F ON L.FILME_ID = F.FILME_ID

WHERE C.LOGIN = ?

Page 28: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Herança

Estratégias para o mapeamento de herança Uma tabela por hierarquia de classes Uma tabela por subclasse Uma tabela por classe concreta

Page 29: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Herança Uma tabela por subclasse

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping> <class name="br.org.citi.pec.locadora.Cliente" table="Clientes"> <id name="login" column="LOGIN" />

... <joined-subclass

name="br.org.citi.pec.locadora.ClienteEspecial" table="ClientesEspeciais">

<key column="LOGIN" /> <property ... /> ... </joined-subclass>

</class></hibernate-mapping>

Page 30: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Otimizando

Como otimizar? Minimizando a leitura de linhas das

tabelas Minimizando a quantidade de comandos

SQLs enviados

Page 31: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Otimizando

Minimizando a leitura de linhas das tabelas Usar lazy fecthing

Minimizando a quantidade de comandos SQLs enviados Usar outer join fetching

Page 32: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Otimizando

Problemas Usar lazy fecthing

• Problema dos n+1 selects (muitos selects!)

Usar outer join fetching• Problema do produto cartesiano (grandes

conjuntos de dados)

Page 33: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Otimizando

Solucionando problemas de otimização Stratégia de Fecthing definida em

tempo de execução Batch Fecthing Utilizar um cache de segundo nível

Page 34: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Consultas

HIbernate Query Lanuage Permite que se expresse quase tudo o

que se precisa expressar em SQL, porém mais orientado a objetos

Três maneiras de se fazer consultas no Hibernate HQL Criteria SQL nativo

Page 35: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

HQL

Tornar SQL orientado a objetos Classes e propriedades ao invés de Tabelas e colunas Polimorfismo Associações

Total suporte a operações relacionais Joins Projeções Funções agregadas e agrupamento Ordenação SubQueries Chamadas a funções SQL

Page 36: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

HQL

A consulta mais simples possivel HQL

from Filme

Devolva todos os filmes

List filmes = session.createQuery(“from Filme”).list();

As consultas podem ser paginadas

Query query = session.createQuery(“from Filme”);query.setFirstResult(20);query.setMaxResults(30);

List filmes = query.list();

Page 37: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

HQL

Uma consulta com ordenação

from Locacao l order by l.dataLocacao desc

Caso esteja interessado em um único resultado

Query query = session.createQuery(“from Locacao l order by l.dataLocacao desc”);

Locacao locacao = query.uniqueResult();

Page 38: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

HQL

Uma consulta com joins

select c from Cliente c left join [fetch] c.locacaoes l

where l.dataLocacao > 3/5/2005

Todos os clientes com suas locações efetuadas após o dia 3

Definição da estratégia de fetching Com o fetch: Coleções já inicializadas Sem o fetch: lazy collections

Page 39: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

HQL

HQL suporta os mesmos operadores que SQL

Operadores do HQL: Comparação: =, <>, <, >, >=, <=, between, not

between, in, not in

Nulidade: is null, is not null

Aritméticos: +, -, /, *, %, parênteses

O operador like funciona da mesma forma que SQL

Pode usar funções SQL se o banco suportar

Page 40: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

HQL

Projeções + funções agregadas (Report Queries)

select c.nome, count(l)

from Cliente c, c.locacoes l

where l.dataLocacao between(:inicio, :fim)

group by c.nome

order by count(l)

Page 41: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

HQL

Os dados da consulta anterior serão retornados em List de Object[]

Consulta comum para a realização de relatórios

Podemos tornar o processo mais elegante

List list = session.createQuery( “select new ClienteReportRow(c.nome, count(l)) ” +

“from Cliente c, c.locacoes l ” + “where l.dataLocacao between(:inicio, :fim) ” + “group by c.nome ” + “order by count(l)”). setDate(“inicion”, inicio). setDate(“fim”, fim).list();

Page 42: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

HQL

Dessa evitasse o uso de vetores de objetos

É necessário que exista uma classe e um construtor previamente definido

Page 43: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

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()

Mas antes, ela precisa ser declarada em algum arquivo de mapeamento

List clientes = session.getNamedQuery(“findClienteByName”)

.setString(“nome”, nome),list()

<query name=“findClienteByName”><![CDATA[from Cliente c where c.nome like :nome]]

</query>

Page 44: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Modelagem OO

“Mais classes que tabelas” Classse Endereco

• Propriedade: rua, numero, bairro... Rua, numero, bairro,... Colunas da

tabela cliente<class name="br.org.citi.pec.locadora.Cliente"

table="Clientes">

<component name=“endereco” class=“br.org.citi.pec.locadora.Endereco”>

<property name=“rua” column=“rua”/>

<property name=“numero” column=“numero”/>

</component>

</class>

Page 45: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

O que mais?

Hibernate também dá suporte a tipos de dados definidos pelo usuário

Interceptadores e EventListeners Filtros Definições explicitas dos SQLs de

insert e update e load (hibernate 3)

...e mais um pouco!

Page 46: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Sobre configuração

Como obter um SessionFactory? Programaticamente Por arquivo XML

Page 47: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Configuração programática

Configuration cfg = new Configuration().setProperty("hibernate.dialect",

"org.hibernate.dialect.HSQLDialect")..setProperty("hibernate.connection.driver_class",

"org.hsqldb.jdbcDriver").setProperty("hibernate.connection.url",

"jdbc:hsqldb:file:hsqldb/data").setProperty("hibernate.connection.username", "sa").setProperty("hibernate.connection.password", "").addClass(Filme.class).addClass(Cliente.class).addClass(Locacao.class);

SessionFactory sessionFactory = cfg.buildSessionFactory();

Page 48: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Configuração XML

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration> <session-factory> <property name="hibernate.dialect">

org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.connection.driver_class">

org.gjt.mm.mysql.Driver</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">ftBBvEdiC</property> <property name="hibernate.connection.url">

jdbc:mysql://localhost/lockar</property> <mapping class="br.org.citi.pec.locadora.Filme"/> <mapping class="br.org.citi.pec.locadora.Locacao"/> <mapping class="br.org.citi.pec.locadora.Cliente"/> </session-factory></hibernate-configuration>

hibernate.cfg.xml

Configuration cfg = new Configuration().configure();SessionFactory sessionFactory = cfg.buildSessionFactory();

Page 49: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Extras

Hbm2ddl (tool) Gera o schema do BD a partir das XML

de mapeamentos Usado por linha de comando ou pelo ant

<target name="schemaexport"> <taskdef name="schemaexport"

classname="org.hibernate.tool.hbm2ddl.SchemaExportTask"classpathref="project.lib.classpath" />

<schemaexport properties="hibernate.properties"

quiet="yes" text="yes" drop="no" delimiter=";"output="${basedir}/sql/schema-export.sql">

<fileset dir="src"> <include name="**/*.hbm.xml" /> </fileset> </schemaexport></target>

Page 50: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Exercícios

Ampliar nosso modelo

Page 51: Hibernate Java avançado – PCC Jobson Ronan {jrjs@cin.ufpe.br} Guilherme Kelly {gkmo@cin.ufpe.br}

Exercícios

Crie as classes (JavaBeans/POJO) Crie os XML de mapeamentos Implemente as consultas e métodos para retornar

Todos os filmes locados durante um determinado mês Listagem contendo nome do filme, média das avaliações, e

total de comentários para todos os filmes Listagem contendo nome do filme mais o número de cópias de

VHS e de DVD desse filme Listagem contendo nome do filme mais o número de cópias de

VHS e de DVD desse filme locadas em um determinado mês Todos os clientes que locaram mais de 5 VHS no ultimo mês

(Com as devidas locações carregadas)