Capítulo 5

Cadastrando Produtos

No capítulo anterior, configuramos o Hibernate para acessar o banco de dados. Neste capítulo, nosso objetivo é cadastrar produtos.

5.1 - Modelando um produto

Agora que estamos com o ambiente configurado e com o banco de dados pronto, podemos partir para a codificação.

A primeira classe que faremos será a classe Produto. Ela representará os produtos que serão cadastrados no sistema, ou seja, quando algum produto for colocado no sistema, nós criaremos uma instância dessa classe.

Nossa classe Produto ficará assim:

public class Produto {
  
  private String nome;
  
  private String descricao;
  
  private Double preco;
  
  // getter e setters
}

BigDecimal

Em aplicações normais, não se deve usar doubles para representar números reais (ex. dinheiro, porcentagem) por causa de problemas de arredondamento. Podemos usar o BigDecimal que tem uma precisão fixa, portanto os problemas de arredondamento são facilmente contornáveis. Não usaremos BigDecimal pois ele é um pouco mais complicado de usar:

double a, b, c, d;
d = a+b/c;

com BigDecimal:

BigDecimal a, b, c, d;
d = a.add(b.divide(c));

5.2 - Anotando a classe Produto

A classe Produto é, por enquanto, uma classe Java normal. Mas precisamos que instâncias dessa classe sejam persistidas ou recuperadas do banco de dados.

Uma das maneiras de transformar essa classe Java normal em uma classe que pode ser persistida é através de XML. O problema dessa abordagem é a dificuldade e o trabalho de se fazer isso com XML.

Outra maneira, que está sendo bem aceita pela comunidade é o uso de anotações para a configuração. Ao invés de usar um arquivo XML para configurar, basta ir na própria classe e anotá-la. Uma das grandes vantagens, além da simplicidade, é que as anotações passam pelo processo de compilação normal, assim como qualquer outro código java. Ou seja, a classe com as anotações deve compilar.

Para anotar a classe Produto, basta colocar na declaração da classe a anotação @Entity, do pacote javax.persistence. Essa anotação pertence a especificação da Java Persistence API.

@Entity
public class Produto {
  
  private String nome;
  
  private String descricao;
  
  private Double preco;
  
  // getter e setters
}

Quando anotamos uma classe com @Entity, devemos indicar qual será o campo de chave primária. Para o nosso caso, vamos criar um campo id para ser a chave primária da tabela.

Para indicar que o campo id será a chave primária, utilizaremos a anotação @Id. Um detalhe importante é que o nome da anotação não é devido ao nome do atributo, ou seja, o atributo e a anotação tem o nome id, mas a anotação sempre será @Id, já o atributo de chave primária pode ser qualquer nome.

Várias vezes não queremos passar o valor do id porque o valor desse campo será gerado no banco de dados. Podemos informar isso pro Hibernate através da anotação @GeneratedValue. Para o nosso caso, esse campo será do tipo auto_increment no banco de dados.

@Entity
public class Produto {
  
  @Id @GeneratedValue
  private Long id;
  
  private String nome;
  
  private String descricao;
  
  private Double preco;
  
  // getter e setters
}

Pronto, agora nossa entidade está devidamente anotada. Só temos que fazer mais uma coisa: avisar o Hibernate dessa entidade, isso porque ele não encontra a entidade automaticamente. Para informar isso ao Hibernate, utilizaremos o arquivo de configuração dele, o hibernate.cfg.xml.

O conteúdo do arquivo ficará assim:

<hibernate-configuration>
  <session-factory>
    <!-- todas as propriedades configuradas anteriormente -->
    
    <!-- entidades -->
    <mapping class="br.com.caelum.goodbuy.modelo.Produto" />
  </session-factory>
</hibernate-configuration>

Repare que temos que utilizar o nome completo da classe, ou seja, o nome da classe mais o pacote.

Saber inglês é muito importante em TI

O Galandra auxilia a prática de inglês através de flash cards e spaced repetition learning. Conheça e aproveite os preços especiais.

Pratique seu inglês no Galandra.

5.3 - Exercícios - Modelando o produto

  1. Crie a classe Produto dentro do pacote br.com.caelum.goodbuy.modelo.

    public class Produto {
      
      private Long id;
      
      private String nome;
    
      private String descricao;
    
      private Double preco;
      
      // getter e setters
    }
    
  2. Anote a classe com as anotações da JPA.

    @Entity
    public class Produto {
      
      @Id @GeneratedValue
      private Long id;
      
      private String nome;
    
      private String descricao;
    
      private Double preco;
      
      // getter e setters
    }
    
  3. Configure essa entidade no Hibernate, alterando o arquivo hibernate.cfg.xml.

    <!DOCTYPE hibernate-configuration PUBLIC
      "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
      "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
    
    <hibernate-configuration>
      <session-factory>
        <!-- todas as propriedades configuradas anteriormente -->
        <!-- -->
        
        <!-- entidades -->
        <mapping class="br.com.caelum.goodbuy.modelo.Produto" />
      </session-factory>
    </hibernate-configuration>
    

5.4 - Adicionando um produto no banco

Para adicionar um produto no banco de dados, precisamos primeiro nos conectar no banco de dados. Quando usamos o JDBC, utilizamos a interface java.sql.Connection, que representa uma conexão com o banco de dados.

Mas no nosso caso, que estamos usando o Hibernate, precisamos usar diretamente essa conexão do JDBC? Não, deixaremos isso para o Hibernate. Temos que lembrar que sempre que quisermos fazer algo no banco de dados, utilizaremos o Hibernate.

Para nos comunicarmos com o banco de dados utilizando o Hibernate, precisamos pedir para o Hibernate um objeto que encapsule uma conexão, e com essa conexão, ele faça o que queremos. Esse objeto que precisamos é a Session, do pacote org.hibernate.

Esse objeto é muito importante para nós porque é ele quem vai encapsular todas as chamadas JDBC, facilitando muito o mecanismo de acesso ao banco de dados.

Nosso primeiro passo para conseguir uma Session é instanciar uma classe que representa a configuração do Hibernate, portanto iniciamos instanciando a classe do Hibernate cujo nome é org.hibernate.cfg.AnnotationConfiguration.

// Cria uma configuração
AnnotationConfiguration configuration = new AnnotationConfiguration();

Depois de criar esse objeto, vamos chamar o método responsável por ler o arquivo hibernate.cfg.xml, o configure().

// Lê o hibernate.cfg.xml
configuration.configure();

Após configurar, precisamos criar um objeto que cria as sessões, uma fábrica. Esse objeto é uma SessionFactory, que pode ser obtida com:

SessionFactory factory = configuration.buildSessionFactory();

Com a SessionFactory em mãos conseguimos criar uma uma Session. O código completo fica:

1 public class TesteDeSessao {
2   public static void main(String[] args) {
3     AnnotationConfiguration configuration = new AnnotationConfiguration();
4     configuration.configure();
5     
6     SessionFactory factory = configuration.buildSessionFactory();
7     Session session = factory.openSession();
8   }
9 }

A partir desse objeto session, basta passarmos uma entidade que ele se encarregará de transformar do modelo orientado a objetos para o modelo relacional.

Produto produto = new Produto();
produto.setNome("Prateleira");
produto.setDescricao("Uma prateleira para colocar livros");
produto.setPreco(35.90);

Transaction tx = session.beginTransaction();
session.save(produto);
tx.commit();

Note que utilizamos uma transação para salvar o produto. Essa transação é do pacote org.hibernate, e ela é necessária para que o insert seja efetivado.

5.5 - Exercícios

  1. Crie a seguinte classe, que adiciona produtos no banco.

     1 package br.com.caelum.goodbuy.testes;
     2 
     3 import org.hibernate.Session;
     4 import org.hibernate.SessionFactory;
     5 import org.hibernate.Transaction;
     6 import org.hibernate.cfg.AnnotationConfiguration;
     7 
     8 public class AdicaoDeProduto {
     9   public static void main(String[] args) {
    10     AnnotationConfiguration configuration = new AnnotationConfiguration();
    11     configuration.configure();
    12     
    13     SessionFactory factory = configuration.buildSessionFactory();
    14     Session session = factory.openSession();
    15     
    16     Produto produto = new Produto();
    17     produto.setNome("Prateleira");
    18     produto.setDescricao("Uma prateleira para colocar livros");
    19     produto.setPreco(35.90);
    20   
    21     Transaction tx = session.beginTransaction();
    22     session.save(produto);        
    23     tx.commit();
    24   }
    25 }
    
  2. Execute a classe que adiciona o produto. Repare no console o sql que foi gerado.

    resultado-console-adicao.png
  3. Acesse o banco de dados e verifique se o produto foi inserido com sucesso.

    resultado-banco-adicao.png
  4. (Opcional) Crie outros produtos no sistema.

Você não está nessa página a toa

Você chegou aqui porque a Caelum é referência nacional em cursos de Java, Ruby, Agile, Mobile, Web e .NET.
Faça curso com quem escreveu essa apostila.

Consulte as vantagens do curso Web ágil com VRaptor, Hibernate e AJAX.

5.6 - Outras operações com produto

Para adicionarmos um produto no banco de dados, utilizamos o método save() da sessão. A sessão do Hibernate possui também métodos de atualização, remoção e busca, e a utilização desses métodos é bem parecida com o que fizemos. Para alterar um produto, basta carregarmos esse produto, alterarmos e depois atualizarmos.

 1 public class AlteracaoDeProduto {
 2   public static void main(String[] args) {
 3     AnnotationConfiguration configuration = new AnnotationConfiguration();
 4     configuration.configure();
 5     
 6     SessionFactory factory = configuration.buildSessionFactory();
 7     Session session = factory.openSession();
 8     
 9     // carrega o produto do banco de dados
10     Produto produto = (Produto) session.load(Produto.class, 1L);
11     
12     Transaction tx = session.beginTransaction();
13     produto.setPreco(42.50);
14     session.update(produto);
15     tx.commit();
16   }
17 }

E para remover um produto:

 1 public class RemocaoDeProduto {
 2   public static void main(String[] args) {
 3     AnnotationConfiguration configuration = new AnnotationConfiguration();
 4     configuration.configure();
 5     
 6     SessionFactory factory = configuration.buildSessionFactory();
 7     Session session = factory.openSession();
 8     
 9     // carrega o produto do banco de dados
10     Produto produto = (Produto) session.load(Produto.class, 1L);
11     
12     Transaction tx = session.beginTransaction();
13     session.delete(produto);
14     tx.commit();
15   }
16 }

5.7 - Exercicios - outras operações com produto

  1. Crie a classe de alteração do produto.

     1 package br.com.caelum.goodbuy.testes;
     2 
     3 public class AlteracaoDeProduto {
     4   public static void main(String[] args) {
     5     AnnotationConfiguration configuration = new AnnotationConfiguration();
     6     configuration.configure();
     7     
     8     SessionFactory factory = configuration.buildSessionFactory();
     9     Session session = factory.openSession();
    10     
    11     // carrega o produto do banco de dados
    12     Produto produto = (Produto) session.load(Produto.class, 1L);
    13     
    14     Transaction tx = session.beginTransaction();
    15     produto.setPreco(42.50);
    16     session.update(produto);
    17     tx.commit();
    18   }
    19 }
    
  2. Execute a classe que altera o produto. Repare no console o sql que foi gerado.

    resultado-console-alteracao.png
  3. Acesse o banco de dados e verifique se o produto foi alterado com sucesso.

    resultado-banco-alteracao.png
  4. Crie a classe de remoção do produto.

     1 package br.com.caelum.goodbuy.testes;
     2 
     3 public class RemocaoDeProduto {
     4   public static void main(String[] args) {
     5     AnnotationConfiguration configuration = new AnnotationConfiguration();
     6     configuration.configure();
     7     
     8     SessionFactory factory = configuration.buildSessionFactory();
     9     Session session = factory.openSession();
    10     
    11     // carrega o produto do banco de dados
    12     Produto produto = (Produto) session.load(Produto.class, 1L);
    13     
    14     Transaction tx = session.beginTransaction();
    15     session.delete(produto);
    16     tx.commit();
    17   }
    18 }
    
  5. Execute a classe que remove o produto. Repare no console o sql que foi gerado.

    resultado-console-remocao.png
  6. Acesse o banco de dados e verifique se o produto foi alterado com sucesso.

    resultado-banco-remocao.png

5.8 - Discussão em sala - mais sobre o Hibernate

Seus livros de tecnologia parecem do século passado?

Conheça a Casa do Código, uma nova editora, com autores de destaque no mercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntos atuais.
Com a curadoria da Caelum e excelentes autores, é uma abordagem diferente para livros de tecnologia no Brasil. Conheça os títulos e a nova proposta, você vai gostar.

Casa do Código, livros para o programador.