Informações
| Tipo: | Tutorial |
|---|---|
| Data de Publicação: | 26/04/2007 |
| Revisado em: | 26/04/2007 |
Vote!
Tags Relacionadas
Comentários ( 11 )
Imprimir
Breve Introdução sobre Hibernate com Anotações
por:
Raphaela Galhardo Fernandes (raphaela@jeebrasil.com.br)
Gleydson Lima (gleydson@jeebrasil.com.br)
Este artigo trata de uma introdução à utilização do framework Hibernate com anotações. Será apresentada uma breve introdução sobre anotações, bem como um exemplo simples de mapeamento objeto relacional com anotações Hibernate.
1. Introdução
Recentemente, o mapeamento objeto relacional utilizando Hibernate passou a ser feito também a partir de anotações, de forma que se tornou mais simples, possibilitando uma maior produtividade no desenvolvimento de aplicações.
As anotações podem ser definidas como metadados que aparecem no código fonte e são ignorados pelo compilador. Qualquer símbolo em um código Java que comece com uma @ (arroba) é uma anotação. Este recurso foi introduzido na linguagem Java a partir da versão Java SE 5.0. Em outras palavras, as anotações marcam partes de objetos de forma que tenham algum significado especial.
A Listagem 1 e a Listagem 2 apresentam exemplo de um tipo de anotação denominado de TesteAnotacao e do seu uso em um método qualquer (metodoTeste), respectivamente. O exemplo é meramente ilustrativo, de forma que o tipo de anotação definido não agrega nenhum significado especial ao código fonte.
public @interface TesteAnotacao{
...
}
Listagem 1 – Exemplo ilustrativo para a criação de um tipo de anotação
@TesteAnotacao
public void metodoTeste{
...
}
Listagem 2 – Exemplo ilustrativo para o uso de um tipo de anotação
Inicialmente, o mapeamento objeto relacional com Hibernate era feito a partir de um conjunto de configurações em arquivos XMLs. Com o surgimento das anotações no Java SE 5.0, o framework Hibernate anexou este recurso, permitindo que as classes Java fossem mapeadas a partir de anotações, simplificando o seu uso. A próxima seção apresentará um exemplo simples do uso da persistência de uma classe com Hibernate Annotations.
2. Exemplo Simples com Anotações Hibernate
Inicialmente, para que o Hibernate soubesse como carregar e armazenar objetos de classes persistentes, eram utilizados apenas arquivos de mapeamento XML. Dessa forma, era possível informar que tabela do banco de dados se refere uma dada classe persistente e quais colunas na tabela são referentes a quais atributos da classe. Com o surgimento das anotações no Java 5.0, tornou-se possível substituir os arquivos XML para o mapeamento objeto relacional. Através do uso de um conjunto de anotações no código fonte das classes mapeadas.
Neste primeiro exemplo, será apresentado como realizar o mapeamento objeto relacional da classe Aluno (Classe ilustrada na Figura 1) utilizando anotações. Dessa forma, informando ao Hibernate que tabela no banco de dados a representa e quais atributos correspondem as quais colunas desta tabela.
Figura 1 - Classe Aluno
A classe Java que representa a entidade Aluno está ilustrada na Listagem 3.
package br.com.jeebrasil.dominio;
public class Aluno {
//Atributos da classe
private int id;
private int matricula;
private String nome;
private long cpf;
//Construtor padrão
public void Aluno(){}
//Métodos getters e setters
public long getCpf() { return cpf; }
public void setCpf(long cpf) { this.cpf = cpf; }
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public int getMatricula() { return matricula; }
public void setMatricula(int matricula) {
this.matricula = matricula;
}
public String getNome() { return nome; }
public void setNome(String nome) { this.nome = nome; }
}
Listagem 3 - Classe de Domínio: Aluno
Para os exemplos ilustrados neste material, a base de dados foi feita utilizando o PostgreSQL 8.2, que pode ser baixado no site www.posgresql.org. A classe Aluno foi mapeada para a tabela aluno presente no esquema anotacoes do banco criado denominado jeebrasil. O script para a criação da tabela aluno pode ser visto na Listagem 4.
CREATE TABLE anotacoes.aluno ( id_aluno integer NOT NULL, -- Identificador da tabela matricula integer NOT NULL, -- Matrícula do aluno nome character(40) NOT NULL, -- Nome do aluno cpf bigint NOT NULL, -- CPF do aluno CONSTRAINT pk_aluno PRIMARY KEY (id_aluno), CONSTRAINT un_cpf_aluno UNIQUE (cpf), CONSTRAINT un_matricula_aluno UNIQUE (matricula) ) WITHOUT OIDS; ALTER TABLE anotacoes.aluno OWNER TO postgres; COMMENT ON COLUMN anotacoes.aluno.id IS 'Identificador da tabela'; COMMENT ON COLUMN anotacoes.aluno.matricula IS 'Matrícula do aluno'; COMMENT ON COLUMN anotacoes.aluno.nome IS 'Nome do aluno'; COMMENT ON COLUMN anotacoes.aluno.cpf IS 'CPF do aluno';
Listagem 4 – Script para a criação da tabela aluno
Todas as classes persistentes mapeadas com anotações Hibernate são declaradas usando a anotação @Entity, aplicada em nível de classes, como mostrado na Listagem 5. Observa-se que com o uso de anotações, não há mais a necessidade de se utilizar arquivos de mapeamento XML adicionais.
Quando o nome da classe é diferente do nome da tabela para a qual é mapeada é necessário informar na anotação @Table qual o nome da tabela, usando o atributo name. No caso do mapeamento da classe Aluno, não havia a necessidade de se informar o nome da tabela, pois ela e a classe possuem o mesmo nome. Como a tabela pertence a um esquema do banco de dados (anotacoes), no mapeamento da classe, também é necessário informar em que esquema a tabela mapeada se encontra, utilizando o atributo schema da anotação @Table. No caso, a linha do código fonte @Table(name="aluno", schema="anotacoes") está informando o nome e o esquema da tabela para a qual está mapeada a classe aluno.
A chave primária da tabela é mapeada na classe através da anotação @Id. O valor atribuído à chave primária pode ser dado tanto pela aplicação quanto por um mecanismo do Hibernate que o gere automaticamente. A anotação @GeneratedValue permite a definição automática para o valor do identificador, utilizando um dos mecanismos de geração apresentados anteriormente. Neste caso, utilizou-se a estratégia a partir de uma seqüência, como feito na linha de código @GeneratedValue(strategy = GenerationType.SEQUENCE). Dessa forma, na hora de persistir uma linha na tabela aluno, o Hibernate vai pegar como valor para a chave primária o próximo valor disponível por uma seqüência padrão chamada hibernate_sequence. Deve-se salientar que o programador deverá criar uma seqüência com este nome na base de dados. Ainda em relação ao identificador, como o nome da coluna mapeada é diferente do nome do atributo, é necessário utilizar a anotação @Column informando o nome da coluna, através do atributo name. Neste exemplo, o nome da coluna mapeada para o identificador é id_aluno, mapeada da seguinte forma: @Column(name="id_aluno").
Observa-se que nos demais atributos da classe não há nenhuma anotação de mapeamento. Isso pode ser feito quando o nome do atributo é igual ao nome da coluna da tabela mapeada, de forma que não há a necessidade de mapeamento explícito.
Por fim, para se utilizar as anotações para mapeamento das classes, é preciso importá-las de algum lugar, neste caso do pacote javax.persistence, como mostrado no início do código fonte da Listagem 10.
package br.com.jeebrasil.hibernate.anotacoes.dominio;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
//Anotação que informa que a classe mapeada é persistente
@Entity
//Informando nome e esquema da tabela mapeada
@Table(name="aluno", schema="anotacoes")
public class Aluno {
//Definição da chave primária
@Id
//Definição do mecanismo de definição da chave primária
@GeneratedValue(strategy = GenerationType.SEQUENCE)
//Informa o nome da coluna mapeada para o atributo
@Column(name="id_aluno")
private int id;
private int matricula;
private String nome;
private long cpf;
public void Aluno(){}
//Métodos getters e setters
//...
}
Listagem 10 – Mapeamento da classe Aluno com anotações
Depois de criar todas as classes persistentes com seus respectivos mapeamentos com anotacoes, deve-se realizar algumas configurações do Hibernate, mostradas na seção seguinte.
2.1 Configurando a Base de Dados
Para tudo funcionar corretamente, é necessário realizar algumas configurações da base de dados. Essas configurações podem ser feitas a partir de um arquivo XML, em geral, denominado hibernate.cfg.xml. A partir deste arquivo, é possível realizar algumas configurações relacionadas à base de dados, bem como informar as classes mapeadas com anotações que poderão ser persistidas a partir dos mecanismos do Hibernate.
A Listagem 6 apresenta um exemplo para o arquivo de mapeamento hibernate.cfg.xml, onde alguns parâmetros são configurados, como:
- A URL de conexão com o banco de dados;
- Usuário e senha do banco de dados;
- Números máximo e mínimo de conexões no pool;
- Dialeto
<?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"><session-factory> <!-- properties --> <property name="connection.driver_class"> org.postgresql.Driver </property> <property name="connection.url"> jdbc:postgresql://localhost:5432/jeebrasil </property> <property name="dialect"> org.hibernate.dialect.PostgreSQLDialect </property> <property name="show_sql">true</property> <property name="connection.username">postgres</property> <property name="connection.password">postgres</property> <property name="connection.pool_size">10</property> <!-- mapping classes --> <mapping class="br.com.jeebrasil.hibernate.anotacoes.dominio.Aluno"/> </session-factory> </hibernate-configuration>
Listagem 6 - Arquivo de Configuração hibernate.cfg.xml
Resumindo as descrições das propriedades configuradas no arquivo hibernate.cfg.xml:
- hibernate.dialect: implementação do dialeto SQL específico do banco de dados a ser utilizado. Usado para identificar as particularidades do banco de dados;
- hibernate.connection.driver_class: nome da classe do driver JDBC do banco de dados que está sendo utilizado;
- hibernate.connection.url: é a URL de conexão específica do banco que está sendo utilizado;
- hibernate.connection.username: é o nome de usuário com o qual o Hibernate deve se conectar ao banco;
- hibernate.connection.password: é a senha do usuário com o qual o Hibernate deve se conectar ao banco;
- hibernate.connection.pool_size: tamanho do pool de conexões;
- hibernate.connection.isolation: define o nível de isolamento. Parâmetro opcional;
- hibernate.show_sql: utilizado para definir se os SQL’s gerados pelo Hibernate devem ou não ser exibidos (true | false).
Já no final do arquivo hibernate.cfg.xml é onde devem ser informados os arquivos das classes mapeadas que o Hibernate deve processar. Se alguma classe não for definida neste local, a mesma não poderá ser persistida utilizando os mecanismos do Hibernate.
Para este exemplo, apenas uma classe foi mapeada. Se existissem outras classes
persistentes, as mesmas deveriam ter linhas semelhantes a
3. Exemplo de Persistência
O Hibernate utiliza objetos Session para persistir e recuperar objetos. Um objeto Session pode ser considerado como uma sessão de comunicação com o banco de dados através de uma conexão JDBC.
O código fonte exibido na Listagem 7 mostra a criação e persistência de um objeto do tipo Aluno.
...
1. try{
2. //SessionFactory deve ser criado uma única vez durante a execução
3 //da aplicação
4 SessionFactory sf = new AnnotationConfiguration()
5. .configure(
6. "/br/com/jeebrasil/hibernate/anotacoes/conf/hibernate.cfg.xml")
7. .buildSessionFactory();
8.
9. Session session = sf.openSession(); //Abre sessão
10. Transaction tx = session.beginTransaction(); //Cria transação
11.
12. //Cria objeto Aluno
13. Aluno aluno = new Aluno();
14. aluno.setNome("Raphaela Galhardo Fernandes");
15. aluno.setMatricula(200027803);
16. aluno.setCpf(1234567898);
17. session.save(aluno); //Realiza persistência
18. tx.commit(); //Fecha transação
19. session.close(); //Fecha sessão
20
21. }catch(HibernateException e1){
22. e1.printStackTrace();
23. }catch(SQLException e2){
24. e2.printStackTrace();
25. }
Listagem 7 - Exemplo de Persistência da Classe Aluno
O código presente nas linhas 4-7 deve ser chamado uma única vez durante a execução da aplicação. O objeto SessionFactory armazena os mapeamentos e configurações do Hibernate. É um objeto pesado e lento de se criar.
A Tabela 1 apresenta alguns dos métodos que podem ser invocados a partir do objeto Session.
| save(Object) | Inclui um objeto em uma tabela do banco de dados. |
| saveOrUpdate(Object) | Inclui um objeto na tabela caso ele ainda não exista (seja transiente) ou atualiza o objeto caso ele já exista (seja persistente). |
| delete(Object) | Apaga um objeto da tabela no banco de dados. |
| get(Class, Serializable id) | Retorna um objeto a partir de sua chave primária. A classe do objeto é passada como primeiro argumento e o seu identificador como segundo argumento. |
Tabela 1 - Métodos invocados a partir do objeto Session
As Listagem 8 e Listagem 9 apresentam exemplos dos métodos invocados a partir do objeto Session.
... Session session = sf.openSession(); Transaction tx = session.beginTransaction(); //Busca objeto aluno da base de dados com chave primária = 1 Aluno aluno = (Aluno) session.get(Aluno.class, 1); //Atualiza informação de matrícula. aluno.setMatricula(200027807); //Como o identificador do objeto aluno é diferente de 0, //a sua matrícula é atualizada já que foi alterada session.saveOrUpdate(aluno); tx.commit(); session.close(); ...
Listagem 8 - Exemplo de Busca e Atualização de um Objeto Aluno
... Session session = sf.openSession(); Transaction tx = session.beginTransaction(); Aluno aluno = new Aluno(); //Existe linha na tabela aluno com chave primária = 2 aluno.setId(2); //Deleta aluno com id = 2 da tabela. //Somente necessária informação do seu identificador session.delete (aluno); tx.comiit(); session.close(); ...
Listagem 9 - Exemplo de Remoção de Objeto Aluno
4. Conclusões
Com este artigo, procurou-se passar uma breve introdução sobre a utilização do framework Hibernate utilizando anotações. As anotações surgiram melhorando o desenvolvimento das aplicações com Hibernate, considerando uma melhora de produtividade no que dizia respeito a uso de arquivos XML’s para a realização do mapeamento objeto relacional. Lembrando que o uso de anotações apenas provocou o surgimento de uma nova sintaxe para o mapeamento objeto relacional com Hibernate. Não houve adição de novos recursos ao framework, apenas unificou-se as configurações nas classes Java.
Comentários (11)
- Li superficialmente este artigo, mas ainda sim, continuo com uma dúvida primária. Para q serve o HIBERNATE? Onde ele entra em um projeto de programação de uma aplicativo JAVA! Ele é parecido com o NetBeans 5.0? Obss: Sou iniciante, caso a minha pergunta pareça meio absurda! Atte Sérgio
- postado por Sérgio Santos em 14/05/2007 às 23:21
- Sérgio, sugiro que você leia os artigos iniciais sobre Hibernate aqui no site. Adianto que não tem nada a ver com o NetBeans e que serve para ajudá-lo a trabalhar com bancos de dados em suas aplicações.
- postado por David Pereira em 25/05/2007 às 23:21
- Excelente artigo. Muito claro, sucinto e completo, mesmo pra mim que possuo um conhecimento quase inexistente no assunto.
- postado por Arturo Riter em 08/08/2007 às 23:21
- muito bom. bem didático e foca somente os elementos principais desta ferramenta. parabéns!
- postado por André em 16/08/2007 às 23:21
- Também gostei do artigo. A empresa onde faço estágio utiliza esse framework, portanto pude sanar muitas dúvidas sobre ele. Gostaria de sugerir um tutorial ou artigo sobre o Tapestry 5, pois ele chegou com algumas propostas bastante interessantes.
- postado por Tiago em 26/10/2007 às 23:21
- Artigo Direto, Sucinto, Objetivo e Claro. Parabéns.
- postado por Mukurype em 09/04/2008 às 23:21
- Muito bom
- postado por izabel em 02/07/2008 às 23:21
- Muito bom este artigo. Só não entendi por que não fazer um select diretamente no banco, ao inves de usar Hibernate, qual a vantagem de usar Hibernate e não fazer um select direto no banco e jogar seus valores em um objeto? Me parece muito mais trabalhoso trabalhar com Hibernate do que fazer o banco a parte do sistema e fazer select sempre que precisar recuperear valores, concorda? Abraço!
- postado por Joao maria em 04/10/2008 às 23:21
- João maria, se você acha mais fácil meter o Select dentro do código ao invés de usar hibernate é porque das duas uma: 1 - Você ainda não trabalhou em projetos com mais de 1 ou 2 desenvolvedores... 2 - Seus projetos são pequenos ao ponto que o Hibernate não agregaria muita coisa... Porque em um projeto (Desktop ou WEB) tanto faz, com mais de 100 Casos de uso, alguns CRUDs mais do cansativos e mais do que 5 desenvolvedores envolvidos, colocar tudo em Select com JDBC se torna uma arma mortal... Pode funcionar ?? Claro, mas não é viável, e a probabilidade de algum erro ser em um Select, que só será detectado depois de muita dor de cabeça, é imensa... Espero ter sido claro... Abraços ;)
- postado por Adriano Ohana em 27/04/2009 às 23:21
- Realmente um tutorial do tapestry5 seria ótimo para divulgar esse framework que é espetacular,trabalho com esse framework e na minha opinião deixa jsf no chão,tanto em simplicidade quanto produtividade,e com otalento do pessoal do JEEBrasil o tutorial iria ficar fantástico
- postado por Rafael em 14/07/2009 às 23:21
- Muito bom. Parabéns ! :)
- postado por Jayro Rodrigues em 07/10/2009 às 23:21
