Title: Hibernate
1Hibernate
- Java avançado PCC
- Jobson Ronan jrjs_at_cin.ufpe.br
- Guilherme Kelly gkmo_at_cin.ufpe.br
2O 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
3O que é?
4Pra 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
5Problemas dos BDRs
- Modelagem
- Não há polimorfismo
- Não há herança
- Lógica de negócio
- Stored procedures -gt perca de portabilidade
6Vantagens 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
7- Obviamente, ainda precisamos dos RDBs
8Objetivo
- Aproveitar-se das vantagens oferecidas pelos RDBs
- Isso sem perder a orientação a objetos
9Objetivo Real
- Ter menos trabalho ?
- Ter um DBA feliz ?
10Em prática
11Em prática
- Classe Persistente
- Construtor default
- Pares de Gets e Sets
- 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
12Em prática
- Mapeamento XML
- Metadado legÃvel
- Mapeamento de tabelas e colunas
lt?xml version"1.0" encoding"UTF-8"?gt lt!DOCTYPE
hibernate-mapping PUBLIC "-//Hibernate/Hibernate
Mapping DTD 3.0//EN" "http//hibernate.sourcefo
rge.net/hibernate-mapping-3.0.dtd"gt lthibernate-ma
ppinggt ltclass name"br.org.citi.pec.locadora.Fil
me" table"filmes"gt ltid name"codigo"
column"filme_id"gt ltgenerator
class"native" /gt lt/idgt ltproperty
name"nome" column"nome"/gt lt/classgt lt/hibernat
e-mappinggt
13Em prática
Session session sessionFactory.openSession() Tr
ansaction tx s.beginTransaction() Filme filme
new Filme() filme.setNome(novoNome) session.s
ave(filme) tx.commit() session.close()
Também pode ser usado saveOrUpdate
14Em prática
Session session sessionFactory.openSession() F
ilme 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
15Em prática
Session session sessionFactory.openSession() Tr
ansaction tx s.beginTransaction() Filme filme
(Filme) session.get(Filme.class, new
Integer(filmeId) session.delete(filme) tx.commi
t() session.close()
16Em prática
- Atualizando um objeto (Dirty Checking)
- Obetendo um filme e alterando seu nome
Session session sessionFactory.openSession() Tr
ansaction tx s.beginTransaction() Filme filme
(Filme) session.get(Filme.class, new
Integer(filmeId) filme.setNome(novoNome) tx.com
mit() session.close()
Não é necessário uma chamada explicita do update
17Estado 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
18Estado dos Objetos
- Dirty Checking só funciona em objetos
persistentes - Use update para objetos desacoplados
19Mais prática
- Melhorando nosso modelo...
20Mais prática
package br.org.citi.pec.locadora public class
Cliente private String login private
String CPF private String nome
private Set locacoes new Hashset() //...
Gets e Sets
21Mais 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 //... Gets e Sets
22Mais prática
lt?xml version"1.0" encoding"UTF-8"?gt lt!DOCTYPE
hibernate-mapping PUBLIC "-//Hibernate/Hibernate
Mapping DTD 3.0//EN" "http//hibernate.sourcefo
rge.net/hibernate-mapping-3.0.dtd"gt lthibernate-ma
ppinggt ltclass name"br.org.citi.pec.locadora.Cli
ente" table"Clientes"gt ltid name"login"/gt
ltproperty name"nome" /gt ltproperty
name"cpf" /gt ltset name"locacoes"gt
ltkey column"cliente_login" /gt ltone-to-many
class"br.org.citi.pec.locadora.Locacao"/gt
lt/setgt lt/classgt lt/hibernate-mappinggt
23Mais prática
lt?xml version"1.0" encoding"UTF-8"?gt lt!DOCTYPE
hibernate-mapping PUBLIC "-//Hibernate/Hibernate
Mapping DTD 3.0//EN" "http//hibernate.sourcefo
rge.net/hibernate-mapping-3.0.dtd"gt lthibernate-ma
ppinggt ltclass name"br.org.citi.pec.locadora.Loc
acao" table"Locacoes"gt ltid
name"id"gt ltgenerator class"native" /gt
lt/idgt ltproperty name"dataLocacao" /gt
ltproperty name"dataDevolucao" /gt
ltmany-to-one name"cliente"
class"br.org.citi.pec.locadora.Cliente"
column"cliente_login"/gt ltmany-to-one
name"filme" class"br.org.citi.pec.locadora.Filme
" column"filme_id"/gt
lt/classgt lt/hibernate-mappinggt
24Mais prática
Locacao locacao new Locacao() Locacao.setDataLo
cacao(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.setF
ilme(filme) cliente.getLocacoes().add(locacao)
tx.commit() session.close()
25Otimizando
- Como as coleções são carregadas
- Lazy fetching (Default)
- Eager (Outer Join) fetching
- Indicado nos XML, ou na própria consulta
26Lazy fetching
Cliente cliente (Cliente) session.get(Cliente.cl
ass, 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 ?
27Outer join fetching
Cliente cliente (Cliente) session.get(Cliente.cl
ass, login) SELECT FROM CLIENTES C LEFT
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 ?
28Herança
- Estratégias para o mapeamento de herança
- Uma tabela por hierarquia de classes
- Uma tabela por subclasse
- Uma tabela por classe concreta
29Herança
lt?xml version"1.0" encoding"UTF-8"?gt lt!DOCTYPE
hibernate-mapping PUBLIC "-//Hibernate/Hibernate
Mapping DTD 3.0//EN" "http//hibernate.sourcefo
rge.net/hibernate-mapping-3.0.dtd"gt lthibernate-ma
ppinggt ltclass name"br.org.citi.pec.locadora.Cli
ente" table"Clientes"gt ltid name"login"
column"LOGIN" /gt ... ltjoined-subclass n
ame"br.org.citi.pec.locadora.ClienteEspecial"
table"ClientesEspeciais"gt ltkey
column"LOGIN" /gt ltproperty ... /gt
... lt/joined-subclassgt lt/classgt lt/hibernate-m
appinggt
30Otimizando
- Como otimizar?
- Minimizando a leitura de linhas das tabelas
- Minimizando a quantidade de comandos SQLs enviados
31Otimizando
- Minimizando a leitura de linhas das tabelas
- Usar lazy fecthing
- Minimizando a quantidade de comandos SQLs
enviados - Usar outer join fetching
32Otimizando
- Problemas
- Usar lazy fecthing
- Problema dos n1 selects (muitos selects!)
- Usar outer join fetching
- Problema do produto cartesiano (grandes conjuntos
de dados)
33Otimizando
- Solucionando problemas de otimização
- Stratégia de Fecthing definida em tempo de
execução - Batch Fecthing
- Utilizar um cache de segundo nÃvel
34Consultas
- 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
35HQL
- 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
36HQL
- 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()
37HQL
- 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()
38HQL
- Uma consulta com joins
- select c from Cliente c left join fetch
c.locacaoes l - where l.dataLocacao gt 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
39HQL
- HQL suporta os mesmos operadores que SQL
- Operadores do HQL
- Comparação , ltgt, lt, gt, gt, lt, 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
40HQL
- 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)
41HQL
- 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()
42HQL
- Dessa evitasse o uso de vetores de objetos
- É necessário que exista uma classe e um
construtor previamente definido
43HQL
- 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(findClient
eByName) .setString(nome, nome),list()
ltquery namefindClienteByNamegtlt!CDATA from
Cliente c where c.nome like nome lt/querygt
44Modelagem OO
- Mais classes que tabelas
- Classse Endereco
- Propriedade rua, numero, bairro...
- Rua, numero, bairro,... Colunas da tabela cliente
- ltclass name"br.org.citi.pec.locadora.Cliente"
table"Clientes"gt -
- ltcomponent nameendereco classbr.org.citi.pe
c.locadora.Enderecogt - ltproperty namerua columnrua/gt
- ltproperty namenumero columnnumero/gt
-
- lt/componentgt
- lt/classgt
45O 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!
46Sobre configuração
- Como obter um SessionFactory?
- Programaticamente
- Por arquivo XML
47Configuraçã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",
- "jdbchsqldbfilehsqldb/data")
- .setProperty("hibernate.connection.username",
"sa") - .setProperty("hibernate.connection.password",
"") - .addClass(Filme.class)
- .addClass(Cliente.class)
- .addClass(Locacao.class)
- SessionFactory sessionFactory
cfg.buildSessionFactory()
48Configuração XML
hibernate.cfg.xml
- lt?xml version"1.0" encoding"UTF-8"?gt
- lt!DOCTYPE hibernate-configuration PUBLIC
- "-//Hibernate/Hibernate Configuration DTD
3.0//EN" - "http//hibernate.sourceforge.net/hibernate-config
uration-3.0.dtd"gt - lthibernate-configurationgt
- ltsession-factorygt
- ltproperty name"hibernate.dialect"gt
- org.hibernate.dialect.MySQLDialectlt/propertygt
- ltproperty name"hibernate.connection.drive
r_class"gt - org.gjt.mm.mysql.Driverlt/propertygt
- ltproperty name"hibernate.connection.usern
ame"gtrootlt/propertygt - ltproperty name"hibernate.connection.passw
ord"gtftBBvEdiClt/propertygt - ltproperty name"hibernate.connection.url"gt
- jdbcmysql//localhost/lockarlt/propertygt
- ltmapping class"br.org.citi.pec.locadora.F
ilme"/gt - ltmapping class"br.org.citi.pec.locadora.L
ocacao"/gt - ltmapping class"br.org.citi.pec.locadora.C
liente"/gt - lt/session-factorygt
- lt/hibernate-configurationgt
Configuration cfg new Configuration().configure(
) SessionFactory sessionFactory
cfg.buildSessionFactory()
49Extras
- Hbm2ddl (tool)
- Gera o schema do BD a partir das XML de
mapeamentos - Usado por linha de comando ou pelo ant
lttarget name"schemaexport"gt lttaskdef
name"schemaexport" classname"org.hibernate.too
l.hbm2ddl.SchemaExportTask" classpathref"project
.lib.classpath" /gt ltschemaexport
properties"hibernate.properties" quiet"yes"
text"yes" drop"no" delimiter"" output"base
dir/sql/schema-export.sql"gt ltfileset
dir"src"gt ltinclude name"/.hbm.xml" /gt
lt/filesetgt lt/schemaexportgt lt/targetgt
50ExercÃcios
51ExercÃ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)