1
|
|
2
|
- Persistência com Hibernate
- Hibernate
- Mapeamento OO-Relacional no Hibernate
- Configuração do Hibernate
- Mapeamento de Classes
- Hibernate Query Language
- Exemplo de Aplicação
|
3
|
|
4
|
- Não é padrão do JCP, mas é quase um padrão de fato do mercado
- Ganhou muito espaço por causa do “preconceito” contra EJBs e da
padronização incompleta do CMP e do JDO
- A versão 3.0 está melhorando muito a documentação e recursos de
otimização
- Incorporado ao JBoss 4.0 como base do seu mecanismo CMP/CMR
- Famoso pela sua flexibilidade em termos de linguagem de consulta (HQL) e
API
|
5
|
|
6
|
- Framework de persistência MOR.
- Um dos mais bem sucedidos e documentados projetos open-source.
- Vantagens
- Modelo natural de programação OO, incluindo herança, composição,
polimorfismo e relacionamentos
com a Collection API
- Transparência de Bando de Dados
- Modelo OO independente da implementação relacional
- Performace
- Dois níveis de cache com suporte a diferentes implementações
- Simplicidade com POJOs (Plain Old Java Objects)
- Integração com JTA
- Comunidade
- Documentação
- Ferramentas
|
7
|
- Um simples POJO mapeado a tabelas no banco através de um arquivo XML.
- POJO (Plain Old Java Object)
- Classe que representa a entidade
- Propriedades, métodos de negócio e relacionamentos
- Exemplo: A entidade Projeto
- Arquivo de mapeamento
- Algoritmos para geração de chave primária
- Nome das tabelas e colunas
- Constraints e Índices
- Relacionamentos e estratégias de extração de dado
- Política de cascade
- Formulas
- Configurações de comportamento de persistência
|
8
|
|
9
|
- Para o Hibernate existem 3 artefatos principais, o POJO, o XML de
Mapeamento e o Schema do banco de dados.
- Ferramentas
- A idéia é que com qualquer um
destes artefatos, seja possível
construir os outros dois
utilizando ferramentas.
- AndroMDA - Model Driven
Achitecture
- Independente da implementação
- Dependente da implementação
|
10
|
- As principais interfaces do Hibernate são
- Session
- Transaction
- SessionFactory
- Configuration
- Query e Criteria API
|
11
|
- Analisando a entidade Projeto
- O único requerimento do Hibernate é a implementação do construtor
default
- Apesar de ser possível mapear um atributo público, é uma boa prática
deixar o atributo privado e criar os métodos de acesso setXXX() e
getXXX()
- O XML de mapeamento
- Além das informações sobre o mapeamento do objeto, podemos configurar
comportamentos relacionados a persistência da entidade, atributos e
relacionamentos
|
12
|
- 2 cenários de utilização do Hibernate:
- standalone
- integrado ao servidor de aplicação
|
13
|
- Modelo 1
- Aplicação fornece as conexões JDBC;
- Aplicação gerencia as transações;
|
14
|
- Modelo 2
- Aplicação não gerencia as transações e não fornece as conexões JDBC;
- Hibernate se integra com as API’s de gerenciamento de transações e
conexões JDBC do servidor de aplicações;
|
15
|
- Persistent Objects / Collections
- Objetos que possuem estado persistente;
- Podem ser simples JavaBeans;
- Estão associados a um objeto Session;
- Transaction (net.sf.hibernate.Transaction)
- Aplicação é “desacoplada” da estratégia de transação (JDBC/JTA/CORBA)
a ser utilizada;
- Um Session pode abrir várias transações;
- ConnectionProvider (net.sf.hibernate.connection.ConnectionProvider)
- Uma fábrica (e pool) de conexões JDBC;
- Aplicação é “desacoplada” do Datasource ou DriverManager utilizado;
- TransactionFactory (net.sf.hibernate.TransactionFactory)
- Uma fábrica de instâncias da classe Transaction;
|
16
|
- Uma instância de um objeto persistente pode estar em um deste três
estados:
- Transient, Persistent ou Detached
- Para um bom desenvolvimento com Hibernate é fundamental entender o
comportamento do objeto
em cada estado, assim
como os eventos que
causam a transição de
um estado para outro.
|
17
|
- Core Interfaces API
- Em Core Interfaces encontramos os principais componentes do Hibernate
que são: Session, SessionFactory, Transaction, Configuration, Query e
Criteria.
- Callback Interfaces
- Temos três interfaces nesta categoria, Validatable, Lifecycle e
Interceptor.
- Validatable e Lifecycle permite que a entidade receba informações
relacionadas a sua própria persistência
- Com Interceptor podemos, por exemplo, realizar auditoria sobre as
operações realizadas com determinada classe persistente.
|
18
|
- Types
- Hibernate suporta todos os tipos primitivos assim como as principais
classes do java, como Calendar, Date, String, etc
- Utilizando a interface UserType podemos criar um novo tipo de dado.
Como por exemplo um tipo de dado que realize sua persistência em duas
colunas na tabela.
- Pontos de extensão
- Com esta API é possível extender as funcionalidades e estratégias do
Hibernate
|
19
|
- Definições:
- SessionFactory (net.sf.hibernate.SessionFactory)
- Threadsafe;
- Cache de mapeamentos objeto-relacional;
- Cliente do Connection-Provider;
- Session (net.sf.hibernate.Session)
- Representa a interação entre a aplicação e o meio de persistência;
- Encapsula uma conexão JDBC;
- Uma fábrica (factory) de transações;
|
20
|
- Transação
- Com JDBC API podemos iniciar uma transação através do método
setAutoCommit(false) da interface Connection
- Em alguns casos temos que trabalhar com transações distribuídas, por
exemplo, se utilizarmos dois banco de dados. Neste caso temos que
utilizar um Transaction Manager que controla a distribuição e o commit
e rollback das transações.
- Hibernate oferece uma camada de transparência relacionada à transação
- Uma chamada a session.beginTransaction() pode resultar em uma JDBC
Transaction ou JTA Transaction
- Lock
- É um mecanismo que permite controlar o acesso concorrente a um registro
- Hibernate permite pessimistic locking (SELECT FOR UPDATE) ou optimistic
locking
|
21
|
|
22
|
- Oferece 3 estratégias de mapeamento de herança
- Table-per-class-hierarchy
- Table-per-concrete-class
- Table-per-subclass
|
23
|
- Dirty Checking
- Quando uma entidade é carregada do banco de dados e alterada, Hibernate executa update
apenas das colunas que realmente foram alteradas
- Projeto projeto = (Projeto) session.load(Projeto.class,
-
new Long(1)) ;
- projeto.setNome(“Alterado”)
- --> update projeto set nome = 'Alterado'
|
24
|
- Transitive Persistence
- Com Transitive Persistence, se uma Collection que representa um
relacionamento é alterada, ou seja, foi adicionado e/ou removido um
Objeto, Hibernate automaticamente insere e/ou remove os registros na
tabela do banco de dados, de acordo com sua política de cascade
- projeto.addRegistro(new Bug(“Novo Bug”) ;
- --> insert into bug ...
- --> update bug set projeto = 1
|
25
|
- Hibernate nos oferece três opções para extração de dados:
- Hibernate Query Language (uma linguagem muito parecida com SQL), a
Criteria API ou ainda com SQL nativo.
- Hibernate Query Language
- Linguagem utilizada para extração de dados Orientada a Objetos
- HSQL oferece quase tudo o que você encontra em SQL de like, upper(),
sum(), avg(), in, some, group by até funções especiais para trabalhar
com Collection.
- Sub queries em clausulas where
- Outer, left e implícito join
|
26
|
- Hibernate Query Language (cont.)
- Named Parameter e Parameter List deixam a query mais simples e legível
- Com Projection é possível extrair individualmente as propriedades da
entidade
- Dynamic Instantiation deixa seu relatório mais simples e organizado
- Query Polimôrficas
- Com queries polimórficas podemos extrair a entidades de tabelas
diferentes fazendo uma única query
|
27
|
- Criteria API
- Uma mais orientada a objetos de extração de dados
- Onde por exemplo um like se transforma em uma chamada ao método
Expression.like() e um join em um createAlias()
- Query Nativa
- Hibernate oferece suporte a execução de query nativas
- Com este suporte, não há a necessidade de amarrar a query com nome de
tabelas e colunas
|
28
|
- Paginação com setFirstResult() e setMaxResult()
- Para todas as opções de consulta com Hibernate, temos disponível a
paginação
- A implementação da paginação depende do banco de dados que se esta
utilizando, mas para a aplicação é transparente.
- No caso do Oracle por exemplo, Hibernate controla a paginação
utilizando rownum
|
29
|
- Tipos de relacionamentos
- Unidirecional e Bidirecional
- Cardinalidade
- Um para muitos ou muitos para um
- Relacionamento muitos para muitos
- Relacionamento Polimórfico
- CMP 2.0 e Hibernate
- Diferentemente de CMP 2.0, Hibernate não implementa CMR (Container
Management Relationship)
- É uma boa prática a implementação de métodos conveniente para
relacionar entidades
|
30
|
- Com Hibernate temos o design OO independente da implementação
relacional,
dessa forma podemos ter granularidade
em OO mapeada
a uma única tabela no BD.
- Diferença entre Entidade e Valor
- Entidade é independente, possui um
único ID e pode ser
trabalhada diretamente
- Valor tem seu ciclo de vida
dependente da Entidade
relacionada.
|
31
|
- Para a uma entidade que possui relacionamento, podemos escolher entre 4
estratégias Immediate, Eager, Lazy e Batch fetching, que define como as
entidades relacionadas serão carregadas.
- Immediate Fetching
- Carrega as entidades relacionadas imediatamente, utilizando um select
na seqüência do outro.
- Eager Fetching
- Indica para o Hibernate que as entidades devem ser carregadas
utilizando um único acesso ao banco, o que implica na utilização de um
outer join.
- Lazy Fetching
- Carrega somente a entidade principal, e quando necessário, as
entidades relacionadas.
- Batch Fetching
- É uma técnica que permite melhoria na estratégia Lazy.
|
32
|
|
33
|
- Uma aplicação pode ser configurada para utilizar diversos bancos de
dados;
- O objeto Configuration é responsável pelo “parsing” dos mapeamentos
objeto-relacionais declarados nos arquivos *.xml;
- O objeto Configuration pode ser instanciado diretamente pela aplicação;
|
34
|
- Um objeto SessionFactory é construído a partir do objeto Configuration;
A partir de sua construção não é mais necessária a utilização do objeto
Configuration;
- A Configuração do SessionFactory pode ser feita das seguintes maneiras:
- Através do arquivo hibernate.properties (raiz do classpath);
- Através do arquivo hibernate.cfg.xml (raiz do classpath);
- Via programação;
|
35
|
- Cada SessionFactory deve ser configurado a partir de um único arquivo de
configuração xml;
- O SessionFactory pode abrir novas sessões a partir de uma conexão JDBC
fornecida pelo usuário;
- As conexões JDBC podem ser obtidas pelo próprio Hibernate, a
configuração das conexões deverá ser feita através dos arquivos de
configuração (hibernate.properties ou hibernate.cfg.xml);
|
36
|
- Principais parâmetros para a configuração das conexões JDBC:
- hibernate.connection.driver_class
- hibernate.connection.url
- hibernate.connection.username
- hibernate.connection.password
- hibernate.connection.pool_size
- O Hibernate pode utilizar as seguintes implementações de connection
pooling: C3P0, Apache DBCP e Proxool;
|
37
|
- Em servidores de aplicação o Hibernate pode obter conexões através de
datasources registrados via JNDI.
- Os principais parâmetros são:
- hibernate.connection.datasource -> Nome JNDI do datasource;
- hibernate.jndi.url -> URL do JNDI provider;
- hibernate.jndi.class (opcional) -> Classe factory do InitialContext
- hibernate.connection.username
- hibernate.connection.password
|
38
|
- Outros parâmetros de configuração do Hibernate:
- hibernate.dialect
- hibernate.default_schema -> coloca automaticamente o nome do esquema
antes do nome dos objetos do bd durante a geração do SQL;
- hibernate.session_factory_name -> Nome JNDI que o session factory será registrado;
- hibernate.use_outer_join -> Utiliza outer join sempre que possível;
|
39
|
- hibernate.connection.provider_class -> Nome da classe
ConnectionProvider;
- hibernate.cache.provider_class -> Nome da classe CacheProvider;
- hibernate.transaction.factory_class -> Nome da classe
TransactionFactory;
- jta.UserTransaction -> Nome JNDI utilizado pela classe
JTATransactionFactory para obter a classe
javax.transaction.UserTransaction
- hibernate.show_sql -> Exibe os SQL’s gerados pelo Hibernate;
|
40
|
- SQL Dialects
- Dialetos SQL possibilitam que o Hibernate tire proveito de
características próprias dos SGBD’s;
- Principalmente no caso da utilização de mecanismos de sequences e
generator’s nativos;
- Deve ser configurado utilizando o nome completo de uma subclasse de
“net.sf.hibernate.dialect.Dialect”
- Exemplo: hibernate.dialect=net.sf.hibernate.dialect.PostgreSQLDialect
|
41
|
- Logging
- O Hibernate utiliza o Apache Commons-logging, o qual redireciona a
saída através do log4j ou da API de logging do JDK 1.4;
- Para utilizar o log4j é necessário que os arquivos “log4j.jar” e
“log4j.properties” sejam acessíveis através do classpath da aplicação;
|
42
|
|
43
|
- Os mapeamentos são declarados em um ou vários arquivos *.xml (Hibernate
mapping files);
- Principais regras para classes persistentes:
- Devem possuir métodos “get” e “set” para os atributos persistentes;
- Devem possuir um construtor padrão (implícito ou explícito) para que o Hibernate possa instanciar
classes através do método “newInstance()”;
- Devem possuir um atributo identificador (não obrigatório para
“Dependent objects”), de forma a possibilitar “cascade updates” e
chamada de método saveOrUpdate (inteligente);
- Não devem ser “final” de forma a possibilitar o uso de proxies;
|
44
|
- Principais elementos dos Hibernate mapping files:
- <class> - Define a classe persistente e a tabela do BD;
- <id> - Define o atributo que será o identificador da instância da
classe e o tipo de generator que será utilizado pelo atributo id;
- <composite-id> - Utilizado para mapear classes para tabelas que
possuem chaves compostas;
- <property> - Define o mapeamento de um atributo persistente, caso o atributo já tenha sido
definido nos elementos <id> ou <composite-id> ocorrerá um
erro;
- <many-to-one> - Define o lado “one” um relacionamento “um para
muitos”;
- <one-to-one> - Define um lado “one” de um relacionamento “um para
um”;
|
45
|
- <component> - Define o mapeamento dos atributos de uma classe
dependente para colunas da tabela mapeada para a classe pai;
- <dynamic-component> - Define que um Map seja mapeado como um
componente onde as propriedades do componente serão as chaves do
elementos do Map;
- <subclass> - Define o mapeamento dos atributos de uma subclasse
para colunas da tabela mapeada para a classe pai. É necessário definir
um atributo “discriminador” na classe pai, além de um valor
discriminante para cada classe da hierarquia. Persistência Polimórfica;
|
46
|
- <joined-subclass> - Define o mapeamento dos atributos de uma
subclasse para colunas de uma tabela mapeada para a subclasse. É
necessário definir um elemento chave <key>, o qual irá apontar
para a chave estrangeira da tabela que foi mapeada para a classe pai.
Não é necessário definir um elemento “discriminador”;
|
47
|
- Tipos do Hibernate
- Tipos básicos:
- integer, long, short, float, double, character, byte, boolean, yes_no,
true_false – Tipos primitivos Java ou Wrapper classes são mapeados para
os correspondentes tipos de dados do SQL;
- string – mapeado para tipos de dados VARCHAR;
- date, time, timestamp - java.util.Date são mapeados para os tipos de
dados SQL (DATE, TIME e TIMESTAMP);
- calendar, calendar_date - java.util.Calendar são mapeados para os tipos
de dados SQL (TIMESTAMP e DATE);
|
48
|
- big_decimal - java.math.BigDecimal para o tipo de dados SQL NUMERIC ou
equivalente.
- locale, timezone, currency - java.util.Locale, java.util.TimeZone e
java.util.Currency para o tipo de dados SQL VARCHAR.
- class - java.lang.Class para o tipo de dados SQL VARCHAR. A Classe é
mapeada utilizando o seu nome completo.
- binary - byte arrays para o tipo binário SQL apropriado.
- text – Strings Java strings para o tipo de dados SQL CLOB ou TEXT.
- serializable – Classes javas serializáveis para o tipo binário SQL
apropriado.
|
49
|
- Tipos enumerados persistentes
- Implementar a interface “net.sf.hibernate.PersistentEnum”;
- Tipos definidos pelo usuário
- Implementar a interface “net.sf.hibernate.UserType” ou
“net.sf.hibernate.CompositeUserType”;
- Os tipos declarados acima necessitam que o seu nome completo seja
informado no atributo “type” do elemento <property>;
|
50
|
- Pode persistir instâncias de java.util.Map, java.util.Set, java.util.SortedMap,
java.util.SortedSet, java.util.List;
- O Hibernate irá trocar as instâncias de Map, Set e List pelas suas
implementações. A principal razão desta estratégia é o suporte a “Lazy
instantiation”;
- <set>, <list>, <map>, <bag>, <array> e
<primitive-array> são os elementos que podem ser mapeados pelo
Hibernate;
|
51
|
- A Java Collections Framework não possui uma interface Bag. Uma “bag”
seria uma coleção de elementos não-indexados e não-ordenados que podem
repetir o mesmo elemento inúmeras vezes. O Hibernate permite que uma bag
seja implementada através de uma “property” List ou Collection;
- Os elementos de uma coleção podem ser mapeados das seguintes maneiras:
<element>, <composite-element>, <one-to-many>,
<many-to-many>;
|
52
|
|
53
|
- Polimórfica
- Ex: “from java.lang.Object o” retorna todos os objetos persistentes;
- “from hibtest.ClienteDO cli where cli.class = hibtest.ClientePJDO”-
Retorna todos os clientes mapeados para a subclasse
“hibtest.ClientePJDO”
- Funções de Agregação: avg(...), sum(...), min(...), max(...), count(*),
count(...), count(distinct ...)
|
54
|
- Cláusula SELECT
- “select elements(f.produtos) from hibtest.FornecedorDO f” – Retorna as
coleções de produtos associadas aos fornecedores retornados, através da
função “elements”;
- Cláusula WHERE
- Possui várias expressões e funções úteis;
- “from hibtest.FornecedorDO f
where size(f.produtos) > 10” – Retorna os fornecedores que
possuem mais de 10 produtos associados;
- Suporte a “group by”;
- Suporte a subquery’s;
- Suporte a “Named parameters”;
|
55
|
- SchemaExport
- Geração de “schema” de banco de dados a partir dos arquivos de
mapeamento do Hibernate;
- Possibilita atualizações incrementais;
- CodeGenerator
- Geração de código a partir dos aquivos de mapeamento do Hibernate;
- Possibilita a criação de classes de busca (Finder classes);
- MapGenerator
- Geração dos arquivos de mapeamento do Hibernate a partir das classes
persistentes;
- Melhor utilizar o XDoclet;
|
56
|
|
57
|
- O cenário da aplicação
- Modelo Relacional
- Existente, Inteiramente novo ou parcialmente novo
- Configuração
- Servidor de aplicação, Spring, Properties, XML, etc.
- Transação
- Controle transacional JDBC ou JTA; nível read-commited, etc.
- Data Access Object - DAO
- O pattern DAO (Data Access Object) consiste na separação do código
relacionado ao acesso dos dados, do código de negócio.
- Utilizando DAO com Hibernate podemos deixar transparente o uso do
Hibernate para o código de negócio.
- Uso de Data Transfer Objects – DTO
- Com Hibernate não existe a necessidade de trabalhar com DTOs
|
58
|
- Classes persistentes
- Entidade, Herança e Relacionamentos
- Transação
- Classes Utilitárias
- Data Access Object
- DAOFactory
- ProjetoDAO e ProjetoDAOHibernate, RegistroDAOHibernate
|
59
|
- Negócio
- Registro.close()
- BugTrackerManager
- Controller e Apresentação
- Automatizar o maior número possível de tarefas
- Ambiente de teste que dependa o mínimo possível de recursos externos ao
sistema
- Automatizando tarefas com Ant
- Compilação, Arquivo jar e war
- Gerando o mapeamento com Xdoclet
- Gerando o script do banco de dados
|
60
|
- Ambiente de testes
- Mock Objects: Implementações falsas de recursos que são utilizadas em
rotinas de testes, como por exemplo da API JDBC
- Junit e HSQL: Pelo fato de Hibernate oferecer transparência, podemos
utilizar um banco de dados em memória para servir de recurso de nossas
rotinas de teste. Independente de qual será o banco de dados de
produção.
|
61
|
- Uma explicação simples sobre o desenvolvimento no Hibernate:
- Crie as tabelas do BD
- Crie um bean representando o objeto codificado.
- Crie um arquivo de mapeamento para que o Hibernate saiba quais
atributos correspondem aos campos SQL.
- Crie um arquivo de configuração informando o Hibernate sobre as
configurações do BD.
- Comece a utilizar a API do Hibernate
- Existem ferramentas que auxiliam na geração de Beans a partir de SQL ou
o contrário (e até plug-ins que criam o arquivo de mapeamento
automaticamente).
|
62
|
- 1o Passo: Criar a tabela
- Para simplificar vamos usar apenas uma tabela de usuários.
- CREATE TABLE usuario (
- Login varchar(20) NOT NULL
default '0',
- Nome varchar(40) default NULL,
- Senha varchar(20) default NULL,
- Email varchar(40) default NULL,
- UltimoAcesso datetime default
NULL,
- PRIMARY KEY (Login)
- );
|
63
|
|
64
|
|
65
|
|
66
|
|
67
|
|
68
|
|
69
|
|
70
|
|
71
|
- Passos A e B
- O objeto de configuração é baseado no arquivo de configuração
(hibernate.properties).
- Configuration config = new
Configuration();
- Config.addClass(Usuario.class);
|
72
|
|
73
|
|
74
|
|
75
|
- package com.ismael.demo;
- import org.hibernate.*;
- import org.hibernate.cfg.Configuration;
- import com.ismael.demo.Usuario;
- import java.util.Date;
- public class UsuarioTest {
- public static void main(String[]
args) throws Exception{
- // Cria a configuração baseado
no arquivo de configuração
- Configuration config = new
Configuration();
- // Informa quais as classes
mapeadas.
- config.addClass(Usuario.class);
|
76
|
|
77
|
|