1 Hibernate Introdução Caio Nakashima [email protected] [email protected].

40
1 Hibernate Introdução Caio Nakashima [email protected] [email protected]

Transcript of 1 Hibernate Introdução Caio Nakashima [email protected] [email protected].

Page 1: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

1

Hibernate Introdução

Caio Nakashima

[email protected]

[email protected]

Page 2: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

2

Primeira Aplicação

• Será criada uma aplicação simples baseado no console do Hibernate.

• O banco de dados neste exemplo poderá armazenar eventos que se deseja atender e informações sobre o anfitrião destes eventos.

• O primeiro passo é configurar a pasta de desenvolvimento e colocar todas as bibliotecas Java necessárias nele.

• Abaixar a distribuição do Hibernate do site http://www.hibernate.org ou da pasta do servidor.

Page 3: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

3

Bibliotecas necessárias

• +lib– antlr.jar– cglib-full.jar– asm.jar– asm-attrs.jars– commons-collections.jar– commons-logging.jar– ehcache.jar– hibernate3.jar– jta.jar– dom4j.jar– log4j.jar

Page 4: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

4

Bibliotecas necessárias

• Extrair o pacote e colocar todas as bibliotecas necessárias que se encontram em /lib para a pasta /lib da pasta de desenvolvimento.

• A lista da transparência anterior é o conjunto mínimo das bibliotecas necessárias.

• É interessante consultar o arquivo README.txt da pasta /lib da distribuição do Hibernate para maiores informações sobre as bibliotecas adicionais de terceiros.

Page 5: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

5

Classe

• Será criada uma classe que representa um evento que se deseja armazenar no banco de dados.

• A classe deste exemplo é uma classe JavaBean com algumas propriedades.

• Observe que a classe utiliza o padrão de nomes do JavaBean para as propriedades dos métodos get e set, assim como a visibilidade dos campos privados.

• Esta é uma recomendação de projeto, mas não é obrigatório.

• Hibernate pode acessar campos diretamente, o benefício de métodos de acesso é a robustez para refactoring.

Page 6: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

6

import java.util.Date;public class Event { private Long id; private String title; private Date date; Event() {} public Long getId() { return id; } private void setId(Long id) { this.id = id; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; }}

Event.java

Page 7: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

7

Identificadores

• A propriedade ID carrega o valor do identificador único para um evento particular.

• Todas as classes de persistência de entidades necessitam de uma propriedade identificadora para utilizar o conjunto completo das características do Hibernate.

• Em geral não se manipula o identificador de um objeto, então o método set deve ser privado. – Somente o Hibernate pode atribuir valores aos identificadores quando

um objeto é salvo.

• Observa-se que o Hibernate pode acessar métodos de acesso public, private e protected assim como os campos diretamente.

Page 8: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

8

import java.util.Date;public class Event { private Long id; private String title; private Date date; Event() {} public Long getId() { return id; } private void setId(Long id) { this.id = id; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; }}

Event.java

Identificadores, definição das interfaces

Page 9: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

9

Construtor

• É necessário um construtor sem argumentos para todas as classes de persistência.– Hibernate tem que criar uma classe utilizando Java

Reflection.

• O construtor pode ser privado, porém a visibilidade do pacote (package) é requerida pelo runtime proxy generation e uma recuperação de dados eficiente sem a instrumentação de bytecode.

• Para o exemplo colocar a fonte Java em uma pasta denominada /src na pasta de desenvolvimento.

+lib

<Hibernate and third-party libraries>

+src

Event.java

Page 10: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

10

import java.util.Date;public class Event { private Long id; private String title; private Date date; Event() {} public Long getId() { return id; } private void setId(Long id) { this.id = id; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; }}

Event.java

Construtores

Page 11: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

11

Arquivo de mapeamento

• É necessário especificar para o Hibernate como carregar e armazenar objeto da classe de persistência.

• O arquivo de mapeamento faz este papel– Especifica qual tabela do banco de dados deve ser

acessado– Quais colunas da tabela devem ser utilizadas.

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

[...]

</hibernate-mapping>

Page 12: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

12

Arquivo DTD

• Pode-se utilizar o arquivo DTD do Hibernate para a auto complementação dos elementos de mapeamento XML e atributos em um editor de programas ou IDE.

• Sugere-se abrir o arquivo DTD para verificar todos os elementos, atributos e valores padrão.

• Hibernate não carregará o arquivo DTD da internet, mas primeiro procura-o no classpath da aplicação.– Esta localizado em .\src\org\hibernate

Page 13: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

13

hibernate-mapping

• Entre duas tags hibernate de mapeamento, incluir uma classe de elemento.

• Todas as classes de persistência de entidade necessitam um mapeamento para uma tabela em uma tabela do banco de dados SQL.

• Abaixo definiu-se como persistir e carregar objetos da classe Event para a tabela EVENTS, cada instância representada por uma linha desta tabela.

<hibernate-mapping> <class name="Event" table="EVENTS"> </class></hibernate-mapping>

Page 14: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

14

Identificador único de entidade

• Para mapear o identificador único para a chave primária da tabela, é necessário configurar a estratégia de geração dos valores para serem colocadas na coluna da chave primária.

<hibernate-mapping> <class name="Event" table="EVENTS"> <id name="id" column="EVENT_ID"> <generator class="increment"/> </id> </class></hibernate-mapping>

Page 15: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

15

Chave primária• O elemento ID é a declaração da propriedade do

identificador.– name="id"

• declara o name da propriedade Java-Hibernate que será utilizada para métodos SET e GET para acessar dos dados.

• O atributo column faz a ligação para o Hibernate qual coluna da tabela EVENTS será utilizado como chave primária.– column="EVENT_ID"

• O elemento generator especifica qual estratégia para gerador de dados.– Neste exemplo está sendo utilizado o método de incremento in-

memory, muito útil para teste.

• Hibernate também suporta geração de valor automáticos pelo banco de dados, assim como identificadores atribuídos pela aplicação.

Page 16: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

16

Propriedades de persistência

• Por padrão nenhuma propriedade da classe é considerada para persistência.

• O nome do atributo da propriedade do elemento indica para o Hibernate qual método get e set deve ser utilizado.

• Por que a propriedade de mapeamento data incluir o atributo da coluna e a propriedade title não?

• Sem o atributo coluna Hibernate por padrão utiliza a propriedade nome como o nome da coluna.

• Date é uma palavra reservada na maioria dos banco de dados, assim é melhor mapear com um nome diferente.

Page 17: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

17

Event.hbm.xml

<hibernate-mapping>

<class name="Event" table="EVENTS">

<id name="id" column="EVENT_ID">

<generator class="increment"/>

</id>

<property name="date" type="timestamp"

column="EVENT_DATE"/>

<property name="title"/>

</class>

</hibernate-mapping>

Page 18: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

18

Forma de mapeamento• Por que o atributo title não tem definido seu tipo?

– Os tipos declarados e utilizados no arquivo de mapeamento não são tipos de dados Java.

– Também não são tipos de dados SQL.

• São tipos denominados Tipos de Dados de Mapeamento Hibernate.– Ele converte tipos de dados Java para tipos de dados SQL e vice

versa.

• Hibernate tenta determinar a conversão correta e mapear tipos de atributos que não estão presentes no arquivo de mapeamento.

• Em alguns casos detecção automática de tipo de dados, utilizando Reflection on Java Class, pode não ter um valor padrão conforme esperado.– Este é o caso da propriedade date.– Hibernate não sabe se a propriedade deve ser mapeada para o tipo

DATE ou TIMESTAMP ou TIME do SQL.

Page 19: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

19

Event.hbm.xml

• O arquivo de mapeamento deve ser salvo com o nome Event.hbm.xml, na pasta onde está armazenado a fonte do Event.java.

• O nome do arquivo pode ser de livre escolha, mas o sufixo deve ser hbm.xml.

• A estrutura de diretório deve ser:

+lib

<Hibernate and third-party libraries>

+src

Event.java

Event.hbm.xml

Page 20: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

20

Exercício

• Criar um arquivo denominado Event.hbm.xml o mapeamento do arquivo. (Pasta src)

<?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="Event" table="EVENTS">

<id name="id" column="EVENT_ID">

<generator class="increment"/>

</id>

<property name="date" type="timestamp" column="EVENT_DATE"/>

<property name="title"/>

</class>

</hibernate-mapping>

Page 21: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

21

Configurando para acessar Postgresql

• Buscar no site do PostgreSql (http://jdbc.postgresql.org/download.html/) os drivers JDBC.

• Colocar na pasta lib o arquivo • Criar na raiz da pasta de desenvolvimento uma

pasta denominada data.+lib

<Hibernate and third-party libraries>

postgresql-8.1-404.jdbc2.jar

+src

Event.java

Event.hbm.xml

+data

Page 22: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

22

Conexão com o banco de dados

• Hibernate é a camada da aplicação que conecta-se com o banco de dados, assim ele necessita de informações sobre a conexão.

• As conexões são efetivadas através de um grupo de conexões JDBC (JDBC connection pool) que deve ser configurado também.

• A distribuição Hibernate contém inúmeras ferramentas de conexões JDBC de código aberto (open source JDBC connection).

• Para a configuração do Hibernate pode utilizar o arquivo hibernate.properties ou hibernate.cfg.xml ou via aplicação.

Page 23: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

23

<?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>

<!-- Database connection settings -->

<property name="connection.driver_class">

org.postgresql.Driver

</property>

<property name="connection.url">

jdbc:postgresql://localhost:5432/postgres

</property>

<property name="connection.username">postgres</property>

<property name="connection.password">1234</property>

Page 24: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

24

<!-- JDBC connection pool (use the built-in) -->

<property name="connection.pool_size">1</property>

<!-- SQL dialect -->

<property name="dialect">

org.hibernate.dialect.PostgreSQLDialect

</property>

<!-- Echo all executed SQL to stdout -->

<property name="show_sql">true</property>

<!-- Drop and re-create the database schema on startup -->

<property name="hbm2ddl.auto">create</property>

<mapping resource="Event.hbm.xml"/>

</session-factory>

</hibernate-configuration>

Page 25: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

25

<session-factory>

• Este arquivo de configuração XML utiliza um arquivo DTD diferente.

• Configura-se Hibernate's SessionFactory uma fábrica responsável por um banco de dados particular.

• Se existirem mais de um banco de dados, utiliza-se inúmeras configurações <session-factory> geralmente um arquivo para cada configuração para facilitar a sua inicialização.

Page 26: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

26

JDBC

• Os primeiros 4 elementos (propriedades) contém as informações necessárias para a conexão JDBC.

<property name="connection.driver_class">

org.postgresql.Driver

</property>

<property name="connection.url">

jdbc:postgresql://localhost:5432/postgres

</property>

<property name="connection.username">postgres</property>

<property name="connection.password">1234</property>

Page 27: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

27

Dialeto• Propriedade do elemento dialeto especifica uma variante

SQL particular gerado pelo Hibernate

• A opção hbm2ddl.auto habilita a geração automática dos esquemas de banco de dados (database schemas) diretamente dentro de banco de dados.• Removendo-se esta opção de configuração pode-se

desligar esta característica. • Pode-se redirecionar para um arquivo com a ajuda do

SchemaExport (ANT)

<property name="dialect"> org.hibernate.dialect.PostgreSQLDialect</property>

<property name="hbm2ddl.auto">create</property>

Page 28: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

28

Event Mapping• Adiciona-se o(s) arquivo(s) de mapeamento para as classes

de persistência. <mapping resource="Event.hbm.xml"/>

.

• Copia-se este arquivo para o diretório fonte, assim completa o classpath.

• Hibernate automaticamente procura por um arquivo denominado hibernate.cfg.xml na raiz do classpath durante a inicialização.

• Criar o arquivo de configuração do Hibernate (hibernate.cfg.xml).

+lib <Hibernate and third-party libraries>+src Event.java Event.hbm.xml hibernate.cfg.xml

Page 29: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

29

Inicialização

• Na inicialização deve incluir a construção de um objeto SessionFactory para armazena-lo em algum lugar para fácil acesso pelo código da aplicação.

• Uma SessionFactory pode abrir uma nova seção.• Uma seção representa uma unidade de trabalho thread

simples (single thread), a SessionFactory é um objeto global de uma thread segura, instanciada uma única vez.

• Será criada uma classe de ajuda HibernateUtil que cuidará da inicialização e fará com que a manipulação da seção seja conveniente.

• Assim o padrão de seção ThreadLocal chamado é útil aqui, para manter a unidade de trabalho corrente com a thread corrente.

Page 30: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

30

SessionFactory

• Esta classe além de produzir uma seção global do SessionFactory em sua inicialização estática (chamada uma única vez pelo JVM quando a classe é carregada), mas também tem uma variável ThreadLocal para armazenar a seção da thread corrente.

• Sempre que for chamado o método HibernateUtil.currentSession() retornará sempre a mesma unidade de trabalho Hibernate em um mesmo thread.

• Uma chamda para o método HibernateUtil.closeSession() finaliza a unidade de trabalho corrente associada com um thread.

Page 31: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

31

Nota: HibernateUtil• Esta classe não é necessária se for implementar o

Hibernate em um servidor de aplicações J2EE:– Um seção será automaticamente limitado pela transação

corrente JTA e pode-se procurar a SessionFactory através do JNDI.

• Se utilizar o servidor de aplicação JBoss, pode se implementado como um serviço de gerenciamento de sistema e será automaticamente associada a SessionFactory para uma nome JNDI.build.xml+lib <Hibernate and third-party libraries>+src Event.java Event.hbm.xml HibernateUtil.java hibernate.cfg.xml+data

Page 32: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

32

Registro de Ocorrências

• Agora é necessário configurar o sistema de registro de ocorrências (logging system).

• Hibernate utiliza commons logging e permite escolher entre Log4j e JDK 1.4 logging.

• A maioria dos desenvolvedores preferem Log4j.– Copiar o arquivo log4j.properties para a pasta /src na

mesma pasta do hibernate.cfg.xml.

• A saída padrão das mensagens de inicialização são apresentadas em stout.

Page 33: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

33

Armazenado e Carregando Objetosimport org.hibernate.Transaction;import org.hibernate.Session;import java.util.Date;public class EventManager { public static void main(String[] args) { EventManager mgr = new EventManager(); if (args[0].equals("store")) { mgr.createAndStoreEvent("My Event", new Date()); } HibernateUtil.sessionFactory.close(); } private void createAndStoreEvent(String title, Date theDate){ Session session = HibernateUtil.currentSession(); Transaction tx = session.beginTransaction(); Event theEvent = new Event(); theEvent.setTitle(title); theEvent.setDate(theDate); session.save(theEvent); tx.commit(); HibernateUtil.closeSession(); }}

Page 34: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

34

• Cria-se um novo objeto Event, que manipula o Hibernate.• Hibernate cuida do SQL e executa as inserções no banco de

dados.• Uma seção é uma simples unidade de trabalho.• Uma unidade de trabalho pode ser mais longa que uma

simples transação no banco de dados.– Exemplo: uma unidade de trabalho que faz inúmeras chamadas http

request/response em uma aplicação web.

• Separar a transação com o banco de dados da unidade de trabalho e com a aplicação do ponto de vista do usuário é um dos conceitos básicos de projeto do Hibernate.

Page 35: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

35

Application Transaction• Pode-de denominar uma unidade de trabalho longa que

geralmente encapsula inúmeras transações pequenas de banco de dados como Application Transaction.

• O API de Transação Hibernate, é opcional, mas é utilizado por sua portabilidade e conveniência.

• Para manipular a transação do banco dados, chamando o método session.connection.commit(), deve-se atribuir um código específico para o ambiente de desenvolvimento.

• Por padrão de configuração do Hibernate pode-se implantar a camada de persistência em qualquer banco de dados.

• No capítulo 12 do Hibernate Reference Documentation pode-se obter mais informações sobre o assunto.

Page 36: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

36

Netbeans Eclipse

Lib localizado em minLib do Hibernate – Postgresql

NetBeans

Page 37: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

37

Eclipse

Lib localizado em minLib do Hibernate – Postgresql

Page 38: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

38

Para adicionar eventos

• Para armazenar eventos, pode-se adicionar uma opção no método main:

sf = new Configuration().configure().buildSessionFactory();Session session = sf.openSession(); //Abre sessaoTransaction tx = session.beginTransaction(); //Cria transacao

//Cria objeto EventoEvent theEvent = new Event();theEvent.setTitle("Evento Novo");theEvent.setDate(new Date());session.save(theEvent);tx.commit(); //Fecha transacaosession.close(); //Fecha sessao

13:45:09,734 DEBUG SchemaExport:301 - drop table EVENTS_POSJAVA13:45:09,890 DEBUG SchemaExport:301 - drop sequence hibernate_sequence13:45:09,906 DEBUG SchemaExport:301 - create table EVENTS_POSJAVA (EVENT_ID int8 not null, EVENT_DATE timestamp, title varchar(255), primary key (EVENT_ID))13:45:10,171 DEBUG SchemaExport:301 - create sequence hibernate_sequence13:45:10,187 INFO SchemaExport:194 - schema export completeHibernate: select nextval ('hibernate_sequence')Hibernate: insert into EVENTS_POSJAVA (EVENT_DATE, title, EVENT_ID) values (?, ?, ?)

Page 39: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

39

listEvents() sf = new Configuration().configure().buildSessionFactory(); Session session = sf.openSession(); //Abre sessao List listaEventos = session.createQuery("from Event").list(); for (int i = 0; i < listaEventos.size(); i++) { Event theEvent = (Event) listaEventos.get(i); System.out.println(" Id:"+theEvent.getId()); System.out.println(" Titulo:"+theEvent.getTitle()); System.out.println(" Data: "+ theEvent.getDate()); } session.close(); //Fecha sessao

• É utilizado aqui HQL (Hibernate Query Language) para consultar e carregar todos os objetos de Eventos existentes do banco de dados.

• Hibernate gerará a expressão SQL apropriada e enviará para o banco de dados e populará os objetos Events com os dados.

Page 40: 1 Hibernate Introdução Caio Nakashima caio.nakashima@mds.gov.br caionakashima@gmail.com.

40

Exercício• Desenvolver um código para criar, inserir e listar os dados da

tabela abaixo:– A) PostgreSQL– B) MySQL

• Analise o exemplo Estado, que lista os dados da tabela estado.• Elabore um exemplo para listar o Municípios.

Pessoa

Pessoa_ID (PK)NomeSexoData_nascimento