Académique Documents
Professionnel Documents
Culture Documents
Rascunho
Autor:Ivan Salvadori
1. Introdução ao JPA com Hibernate.
JPA ou Java Persistence API, é uma padronização da linguagem Java, para mapeamento
objeto/relacional. Em outras palavras, é a padronização de um mecanismo capaz de armazenar no
banco de dados as classes do modelo da aplicação que necessitam de persistência. Este mecanismo
visa promover todos os recursos de banco de dados, sem a necessidade de manipulação direta de
instruções SQL.
Para inserir um cliente, uma classe responsável pela manipulação do banco, geralmente um
DAO, recebe o objeto do tipo Cliente, com as informações desejadas já definidas no objeto. De
posse desse objeto, as informações são extraídas através dos métodos getter's, e inseridas na
instrução SQL de INSERT.
String comando = "insert into Cliente (nome, cpf, rg, telefone ,data_nasc)
values (?, ?, ?, ?, ?)";
java.sql.Connection con;
try {
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/base", "user","senha");
} catch(SQLException e) {
throw new RuntimeException(e);
}
String comando = "insert into Cliente (nome, data_nasc, telefone, rg, cpf)
values (?,?,?,?,?)";
PreparedStatement stmt;
try {
stmt = con.prepareStatement(comando);
stmt.setString(1, cliente.getNome() );
stmt.setDate(2, new
java.sql.Date(cliente.getDataNasc().getTime() ) ); //formata data para sql
stmt.setString(3, cliente.getTelefone() );
stmt.setString(4, cliente.getRg() );
stmt.setString(5, cliente.getCpf() );
stmt.execute();
stmt.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
Para listar os clientes gravados o banco, executa-se um instrução SQL SELECT, com os
dados obtidos do banco é construído um objeto do tipo Cliente, e definido as suas propriedades
através dos métodos setter's.
while (rs.next()) {
Cliente c = new Cliente();
c.setCodigo(rs.getInt("codigo"));
c.setNome(rs.getString("nome"));
c.setRg(rs.getString("rg"));
c.setCpf(rs.getString("cpf"));
c.setTelefone(rs.getString("telefone"));
c.setDataNasc( rs.getDate("data_nasc") );
}
Analisando os mecanismos e códigos ilustrados anteriormente, nota-se que para implementar um
sistema de médio a grande porte, uma esforço consideravelmente grande se faz necessário para
tratar os assuntos de manipulação do banco de dados, observa-se também que as classes com essas
responsabilidades são extensas, qualquer alteração no banco de dados implica em manutenção do
código.
Com os exemplos anteriores, pode-se notar que toda a implementação da persistência dos
dados fica sob responsabilidade do FrameWork, retirando toda a manipulação direta com o banco
de dados. Caso alguma alteração seja feita na classe Cliente, que consequentemente provoque
alguma alteração na tabela que armazena seus dados, nenhum código sofrerá alteração, diminuindo
muito o custo de manutenção. Isso é possível pois o JPA com Hibernate representa uma camada
extra entre a aplicação e o JDBC, até então programado diretamente pelo desenvolvedor.
Aplicação
JPA
Hibernate
JDBC
Banco de Dados
JPA nos possibilita desenvolver toda a persistência com o mínimo de código possível através
de uma forma fantástica, mas como é possível realizar essa facilidade? Será o Assunto dos
próximos capítulos.
2. Entendendo o Framework.
Para que isso seja possível, o Hibernate deve ter conhecimento das informações do objeto
cliente, assim como conhecer os detalhes do banco de dados. É necessário o conhecimento do
conteúdo das tabelas dentre outras informações ligadas ao projeto relacional.
Vamos recorrer ao nosso problema de cadastro de clientes, temos a nossa Classe Cliente que
deve ter as suas propriedades gravadas. A tabela Cliente da suporte para a gravação de todas as
informações da classe. Dessa forma a classe cliente será armazenada na tabela Cliente. Cada
atributo da classe será gravado em uma coluna da tabela com seu respectivo nome. A Ilustração 5
demonstra como deve ser o mapeamento da classe Cliente para a tabela Cliente.
@Entity
@Table(name = "Cliente")
public class Cliente implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(unique=true, nullable=false)
private int codigo;
@Column(length=45)
private String cpf;
@Column(length=45)
private String rg;
@Column(length=45)
private String nome;
@Column(length=45)
private String telefone;
@Column(name = "data_nasc")
@Temporal(TemporalType.DATE)
private Date dataNascimento;
set's()
get's()
}
Repare a presença de estruturas que iniciam com “ @ ”, são as anotações. Existe diferentes
tipos de anotações, cada uma denota uma configuração diferente, definido informações a
componentes que a procedem, vamos explicar algumas:
@Entity - Esta anotação diz que essa classe é uma entidade, portanto será persistida. ( uma
classe é chamada de entidade quando caracterizar necessidade de gravação no banco de dados de
suas propriedades ).
@Table(name = "Cliente") – Anotação responsável por apontar em qual tabela a classe será
armazenada, neste caso na tabela Cliente.
<persistence-unit name="ClienteJPA">
<class>Cliente</class>
<properties>
<property name="hibernate.dialect"
value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<property name="hibernate.connection.driver_class"
value="org.gjt.mm.mysql.Driver" />
<property name="hibernate.connection.url"
value="jdbc:mysql://localhost/nomeDaBase" />
</properties>
</persistence-unit>
</persistence>
Outro conceito que o JPA nos apresenta é o EntityManager, responsável pela execução dos
serviços de persistência do framework. Ele gerencia as entidades, estabelece a conexão com o banco
de dados, executa as operações de gravação, alteração, remoção e seleção das classes anotadas. O
EntityManager é criado baseando-se em no persistence-unit definido no persistence.xml. O
código que segue, demostra a criação do gerenciador.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("ClienteJPA");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(cliente);
em.getTransaction().commit();
em.close();
emf.close();
Para que o objeto seja realmente gravado, deve-se dar a ordem de exucação de gravação,
isso se faz através do código abaixo. Commit concretiza a solicitação do recurso de gravação.
em.getTransaction().commit();
em.getTransaction().begin();
compra = em.find(Compra.class, codigo);
em.getTransaction().commit();
No exemplo acima, uma transação é iniciada, e o método find localiza a partir do código o
objeto, os dois parâmetros da procura são a classe do objeto, que serve de referencia para dizer
aonde procurar, e o código, que diz oque procurar.
O método merge atualiza o registro da tabela do banco que possui o mesmo código do
objeto passado por parâmetro. As ilustrações 6 e 7 mostram o processo de atualização do objeto
cliente.
Ilustração 6: Registro antes da alteração.
cliente.setNome("José Serra");
cliente.setRg("123");
cliente.setCpf("456");
cliente.setTelefone("999");
cliente.setCodigo(5);
em.getTransaction().begin();
em.merge(cliente);
em.getTransaction().commit();
Agora vamos remover o registro que foi alterado no exemplo anterior, seguindo o principio
dos exemplos temos:
Cliente cliente = new Cliente();
cliente.setNome("José Serra");
cliente.setRg("123");
cliente.setCpf("456");
cliente.setTelefone("999");
cliente.setCodigo(5);
em.getTransaction().begin();
em.remove(cliente);
em.getTransaction().commit();
em.getTransaction().begin();
em.persist(cliente);
em.getTransaction().commit();
em.getTransaction().begin();
em.remove(cliente);
em.getTransaction().commit(); ERRO
Ilustração 10: Tentativa de remoção de entidade não gerenciada.
Note que a remoção se aplicou a uma entidade que não estava sendo gerenciada pelo JPA, este é o
motivo do erro. O JPA não pode remover uma entidade que não é gerenciada por ele. Sendo assim, a
entidade que deseja-se remover deve estar sob o domínio do framework. Uma forma de fazer isso é
solicitar que o Hibernate faça a pesquisa da entidade. Toda a entidade selecionada do banco de
dados através do framework, está sob gerenciamento. O código que segue mostra a implementação
da solução encontrada.
em.getTransaction().begin();
Cliente c = em.find(Cliente.class, 5);
em.getTransaction().commit();
em.getTransaction().begin();
em.remove(c);
em.getTransaction().commit();
em.close();
emf.close();
em.getTransaction().begin();
Cliente c = em.find(Cliente.class, 5);
em.getTransaction().commit();
Remoção
Realizada
Resumo do Capítulo:
Iniciamos anteriormente um projeto JSF de cadastro de clientes, que utiliza JDBC para
manipular as operações com o banco de dados, vamos construir uma implementação JPA com
Hibernate para realizar essa tarefa, e veremos as vantagens ao se desenvolver utilizando esta
tecnologia.
Concluída esta etapa, o projeto passa a possuir características JSF e JPA, em outras palavras,
o projeto agrega funcionalidades dos dois Frameworks. Observe que agora está presente o arquivo
de configuração do Hibernate.