Baixar versão 3.0.5 do hibernate em Hibernate Java avançado – PCC Jobson Ronan...
Transcript of Baixar versão 3.0.5 do hibernate em Hibernate Java avançado – PCC Jobson Ronan...
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
Hibernate
Java avançado – PCCJobson Ronan {[email protected]}
Guilherme Kely {[email protected]}
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
O que é?
Hibernate é uma moderna solução de mapeamento objeto-relacional(ORM) Persistência transparente (POJO/Java
Beans) “Lazy Fetching” Uso de uma Cache Três estratégias para o mapeamento de
heranças
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
O que é?
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
Problemas dos BDRs
Modelagem Não há polimorfismo Não há herança
Lógica de negócio Stored procedures -> perca de
portabilidade
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
Obviamente, ainda precisamos dos RDBs
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
Objetivo
Aproveitar-se das vantagens oferecidas pelos RDBs
Isso sem perder a orientação a objetos
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
Objetivo Real
Ter menos trabalho Ter um DBA feliz
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
Em prática
Locadora em partes...
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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; }}
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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>
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
Em prática
Salvando um objeto
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Filme filme = new Filme();
filme.setNome(novoNome);
session.save(filme);
tx.commit();
session.close();
Também pode ser usado saveOrUpdate
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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();
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
Estado dos Objetos
Dirty Checking só funciona em objetos persistentes Use update para objetos desacoplados
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
Mais prática
Melhorando nosso modelo...
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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}
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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>
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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...
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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();
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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>
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
Otimizando
Como as coleções são carregadas Lazy fetching (Default) Eager (Outer Join) fetching
• Indicado nos XML, ou na própria consulta
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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:
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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 = ?
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
Otimizando
Como otimizar? Minimizando a leitura de linhas das
tabelas Minimizando a quantidade de comandos
SQLs enviados
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
Otimizando
Minimizando a leitura de linhas das tabelas Usar lazy fecthing
Minimizando a quantidade de comandos SQLs enviados Usar outer join fetching
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
Otimizando
Problemas Usar lazy fecthing
• Problema dos n+1 selects (muitos selects!)
Usar outer join fetching• Problema do produto cartesiano (grandes
conjuntos de dados)
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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();
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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();
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
HQL
Uma consulta com joins
select c from Cliente cleft join [fetch] c.locacaoes lwhere 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
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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)
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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();
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
HQL
Dessa forma evitas-se o uso de vetores de objetos
É necessário que exista uma classe e um construtor previamente definido
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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>
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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>
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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!
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
Sobre configuração
Como obter um SessionFactory? Programaticamente Por arquivo XML
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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();
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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();
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
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>
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
Exercícios
Ampliar nosso modelo
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
Exercícios
Crie as classes (JavaBeans/POJO) Crie os XML de mapeamentos Implemente as consultas
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)
Baixar versão 3.0.5 do hibernate em http://www.hibernate.org/
Exercício 2
Re-implemetar as classes de repositório do projeto usando o hibernate