Hibernate
Hibernate
Mapeamento Objeto-Relacional
(Object Relational Mapping)
A maioria das aplicações sejam elas construídas para uso no Web ou não,
utilizam algum mecanismo para a persistência de dados
Normalmente utiliza-se algum Banco de Dados que é o responsável pelo
armazenamento (persistência) e pela manutenção dos dados de uma aplicação.
Os banco de dados disponibilizam a linguagem SQL que permite operações de
CRUD (Create; Read; Update; Delete)
Atualmente os dados de dados são criados dentro de um modelo conhecimendo
como relacional.
Neste modelo os dados são vistos como tabelas, onde as colunas
individualmente definem quais os dados armazenados e uma linha representa um
conjunto de dados específico
Em
E uma análise
áli simples,
i l pode-se
d dizer
di que uma linha
li h representa
t um objeto
bj t
Sendo assim uma tabela de um banco de dados poderia ser comparada a um
conjunto de objetos
A semelhança porém, encerra-se aqui
1
12/8/2011
2
12/8/2011
3
12/8/2011
Hibernate
Família de projetos relacionados para ORM (Object Relational Mapping)
Pode ser utilizanda tanto na plataforma Java quando .Net
4
12/8/2011
Configuração básica
A configuração básica pode estar contida em um arquivo XML, chamado
hibernate.cfg.xml ou então um arquivo de propriedades (hibernate.properties)
Mapping Files
Arquivos XML que indicam como os objetos estão ligados com as tabelas de um banco
de dados relacional e como serão persistidos
5
12/8/2011
6
12/8/2011
7
12/8/2011
uuid utiliza um algoritmo de 128‐bits UUID que produz identificadores do tipo string e que são únicos em uma
rede (pois o IP é utilizado pelo algoritmo). O valor é codificado como uma string hexadecimal de tamanho 32
guid Utiliza um String GUID string em bancos MS SQL Server e MySQL.
native Escolhe entre os geradores identity, sequence ou hilo dependendo da capacidade do banco utilizado
assigned Neste caso aplicação é responsável por escolher um identificador para o objeto antes que o método save()
seja chamado. Este é o valor default caso nehum elemento <generator> seja fornecido
select Permite obter a chave primária a partir de um trigger através da seleção do id a partir de alguma tabela
Utiliza o identificador associado com outro objeto. Usualmente utilizado em uma associação <one‐to‐one>
foreign
entre chaves primárias
Programação Orientada a Objetos 2 215
Flávio de Oliveira Silva, M.Sc.
8
12/8/2011
9
12/8/2011
10
12/8/2011
11
12/8/2011
12
12/8/2011
13
12/8/2011
Herança
Considere que a classe Event possui duas subclasses
14
12/8/2011
15
12/8/2011
Hibernate – API
O Hibernate possui um API completa a fim de realizar o acesso ao banco
de dados
Desta forma as operações CRUD (Create; Read; Update; Delete) e
outras podem ser realizadas através da API sem o uso da linguagem
SQL
No geral, quanto menos código SQL existir na camada de persistência,
maior será a independência do banco de dados
O Hibernate fica então responsável por tratar as diferenças no código
SQL para diferentes fornecedores de banco de dados
Entre as principais classes da API do Hibernate pode-se destacar:
Configuration
SessionFactory
Session
Transaction
Query
16
12/8/2011
Hibernate – API
Class Configuration
Esta classe é responsável por iniciar o Hibernate.
Ela é utilizada para carregar os arquivos de mapeamento (mapping files) e além
disso através da mesma é possível obter sessões com o banco de dados, visto
que as informações para acesso ao banco estão no arquivo de configuração do
Hibernate.
O objeto desta classe pode ser descartado assim que a configuração é carregada
e que o objeto SessionFactory é obtido.
A maneira mais simples de carregar a configuração é utilizar o método configure()
public Configuration configure() throws HibernateException
Este método cria e carrega a configuração conforme o arquivo hibernate.cfg.xml
Configuration cfg = new Configuration(); //cria uma configuração “básica”
cfg.configure(); //carrega o arquivo hibernate.cfg.xml
Outro método importante desta classe é o método buildSessionFactory()
public SessionFactory buildSessionFactory() throws HibernateException
Este método retorna um objeto SessionFactory. A partir deste objeto é possível obter
conexões com o banco de dados
Hibernate.cfg.xml
Exemplo
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
< i f t
<session-factory> >
<!-- Database connection settings -->
<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="connection.url">jdbc:hsqldb:hsql://localhost</property>
<property name="connection.username">use</property>
<property name="connection.password">pw</property>
<!-- JDBC connection pool (use the built-in) -->
<!-- <property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<propertyt name="dialect">org.hibernate.dialect.HSQLDialect</property>
"di l t" hib t di l t HSQLDi l t / t
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<mapping resource="org/hibernate/tutorial/domain/Event.hbm.xml"/>
</session-factory>
</hibernate-configuration Programação Orientada a Objetos 2
233
Flávio de Oliveira Silva, M.Sc.
17
12/8/2011
Hibernate – API
Class Configuration - Exemplo
O código abaixo carrega a conexão e cria um objeto SessionFactory
private static SessionFactory factory;
static {
try {
//Configuration cfg = new Configuration();
//cfg.configure();
// factory = cfg.buildSessionFactory();
factory =new Configuration(). configure().buildSessionFactory();
}
catch (HibernateException e) {
e.printStackTrace();
}
}
Desta forma é possível inicializar o Hibernate e além disso utilizar o
objeto SessionFactory a fim de se comunicar com o banco
Hibernate – API
Class SessionFactory
O objeto desta classe é criar sessões (objetos da classe Session) com o banco
de dados
Normalmente uma aplicação contém apenas um objeto desta classe que
centraliza a responsabilidade.
Caso a aplicação manipule deferentes banco de dados simultaneamente é
necessário criar um objeto da classe SessionFactory para cada banco de dados
Métodos Principais
public Session openSession() throws HibernateException
Cria uma conexão com o banco de dados e abre uma sessão com o mesmo
public void close() throws HibernateException
Destrói o objeto SessionFactory e libera todos os recursos (caches, pools de conexões;
etc.)
t )
A aplicação deve garantir que não existem sessões abertas antes de executar
este método.
18
12/8/2011
Hibernate – API
Class SessionFactory - Exemplo
O fragmento de código abaixo mostra o uso do objeto SessionFactory
para se o obter a conexão com o banco de dados.
private static SessionFactory factory;
…
try {
factory = new Configuration().configure().buildSessionFactory();
Session session = factory.openSession();
}
catch (HibernateException e)
e.printStackTrace();
}
Singleton
SessionFactory
package org.hibernate.tutorial.util;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
p
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return new Configuration().configure().buildSessionFactory();
}
catch (Throwable ex) {
System.err.println( Initial SessionFactory creation failed
System err println("Initial failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
Programação Orientada a Objetos 2 237
Flávio de Oliveira Silva, M.Sc.
19
12/8/2011
Hibernate – API
Class SessionFactory
O Hibernate pode ser utilizado basicamente em dois tipos de ambientes:
Ambientes Gerenciados
Neste caso o ambiente é responsável por gerenciar grupos(pools) de
t õ e segurança.
recursos; transações
Um servidor de aplicação J2EE implementa este padrão de trabalho
Ambientes Não-Gerenciados
Nestes ambientes não existem oferecem controle automático de transações,
gerenciamento de recursos (como conexões com o banco, por exemplo) ou
uma infra-estrutura de segurança.
Estas responsabilidades são delegadas à aplicação
Este é o caso de aplicações criadas para desktop ou aplicações Web
existentes em um servlet container como o Tomcat
Hibernate – API
Class SessionFactory
Ambientes Gerenciados
Ambientes Não-Gerenciados
20
12/8/2011
Hibernate – API
Class SessionFactory
Ambientes Não-Gerenciados – Pool de Conexões
No caso de ambientes não gerenciados a aplicação deve ser responsável por criar um
pool (grupo) de conexões de ficam disponíveis
Assim que um o objeto SessionFactory obter uma conexão a mesma é retirada do pool
d l id assim
e devolvida i que ffor ffechada.
h d
O Hibernate possui um mecanismo padrão para gerenciar o pool de conexões, porém o
mesmo é bem básico e deve ser utilizado apenas para testes e não deve ser utilizado
em produção.
A arquitetura do hibernate permite conectar ao mesmo diferentes componentes para
implementam a lógica de um pool de conexões como C3P0, Proxool e Apache DBCP.
O componente padrão é o C3P0
A configuração do C3P0 é feita no arquivo hibernate.cfg.xml
<!
<!-- configuration pool via c3p0-->
c3p0 >
<property name="c3p0.acquire_increment">1</property>
<property name="c3p0.idle_test_period">100</property> <!-- seconds -->
<property name="c3p0.max_size">100</property>
<property name="c3p0.max_statements">0</property>
<property name="c3p0.min_size">10</property>
<property name="c3p0.timeout">100</property> <!-- seconds -->
Programação Orientada a Objetos 2 240
Flávio de Oliveira Silva, M.Sc.
Hibernate – API
Class Session
Este objeto representa a interface ente a aplicação Java e o Hibernate.
E é a principal classe da API do Hibernate.
O objetivo da sessão é executar operações sobre o banco. É possível
criar, ler, alterar e apagar instâncias de classes mapeadas.
Um objeto pode ter os seguintes estados:
Transiente (transient) – Neste caso o objeto nunca foi gravado no banco e
não está associado a nenhuma sessão
Persistente (persistent) – Neste caso o objeto está associado a uma sessão e
já foi gravado no banco de dados.
Desconectado (detached) – Objeto foi gravado anteriormente, porém não
está associado a nenhuma sessão
sessão. Ocorre quando a sessão é fechada
Uma sessão pode conter uma série de objetos associados à mesma
Normalmente uma sessão sempre é envolvida por uma transação
(Transaction)
21
12/8/2011
Hibernate – API
Class Session – Métodos Principais
Serializable save(Object object) throws HibernateException
Transforma um objeto transiente em persistente, antes porém o mesmo
recebe um ID (utilizando o valor da propriedade, ou o gerador definido).
Caso o objeto possua objetos associados a operação é cascateada caso o
atributo cascade = “save-update”
void update(Object object) throws HibernateException
Transforma um objeto transiente em persistente, porém neste caso é utilizado
o Id anterior.
Caso o objeto possua objetos associados a operação é cascateada caso o
atributo cascade = “save-update”
void saveOrUpdate(Object object) throws HibernateException
Utiliza o método save() o update() dependendo do valor do seu ID
Caso o objeto possua objetos associados a operação é cascateada caso o
atributo cascade = “save-update”
Hibernate – API
Class Session – Métodos Principais
void flush() throws HibernateException
Este método força que objetos persistentes, existentes na memória, sejam
sincronizados com o banco de dados.
Quando um objeto é salvo na Sessão o mesmo não é gravado imediatamente
no banco, apenas quando existir um número maior de escritas a fim de
maximizar a performance.
Normalmente é chamado antes do final de uma unidade de trabalho, ou seja,
antes de realizar o commit() da transação e de fechar a sessão.
Quando uma transação é confirmada (commit) o objeto Session é
automaticamente sincronizado não sendo necessário chamar o método
flush()
22
12/8/2011
Hibernate – API
Class Session – Métodos Principais
Object load(Class theClass, Serializable id) throws
HibernateException
Retorna um objeto persistente, a partir do nome de sua classe e do
ID. É necessário que o objeto exista
Caso seja possível que o objeto não exista este método não deve ser
utilizado
Object get(Class clazz, Serializable id) throws
HibernateException
Retorna um objeto persistente, a partir do nome de sua classe e do
ID.
ID Caso o objeto não exista retorna o valor null
Em ambos os casos é necessário conhecer o id, ou seja, a chave
primária do objeto
Em ambos os casos é necessário conhecer o id, ou seja, a
chave primária do objeto
Programação Orientada a Objetos 2 244
Flávio de Oliveira Silva, M.Sc.
Hibernate – API
Class Session – Métodos Principais
void delete(Object object) throws HibernateException
Remove um objeto persistente do banco de dados
Query createQuery(String queryString) throws HibernateException
Cria um objeto Query a partir de uma String que contém uma consulta
baseada na linguagem HQL (Hibernate Query Language)
A linguagem HQL é uma linguagem baseada na linguagem SQL, porém a
mesma permite utilizar uma notação baseada na orientação a objetos.
SQLQuery createSQLQuery(String query) throws HibernateException
Cria um objeto Query a partir de uma String que contém uma consulta
baseada na linguagem HQL (Hibernate Query Language)
public Transaction beginTransaction() throws HibernateException
Inicia uma unidade de trabalho e retorna o objeto associado
(Transaction)
23