Para o nosso exemplo, irei utilizar o banco de dados MySQL, com apenas um tabela chamda bug. Segue o script SQL para criar a tabela:
CREATE TABLE `bug` (
`id_bug` int(11) NOT NULL auto_increment,
`titulo` varchar(60) NOT NULL,
`data` date default NULL,
`texto` text NOT NULL,
PRIMARY KEY (`id_bug`)
);
Preparando o ambiente
Crie uma pasta com o nome bugjpa, coloque-o na sua variável de ambiente chamada CLASSPATH. Não esqueça que os arquivos jar’s devem ficar também no CLASSPATH (ver artigo anterior).
Agora, temos que criar nossa classe de entidade onde iremos mapear nossa classe de acordo com a estrutura da tabela bug. Na listagem 02, está a nossa classe de entidade ou Entity Bean com os devidos atributos mapeados com a anotação @Column(). Note que na campo data, há um anotação diferente @Temporal, esta anotação informa que o nosso campo é do tipo Date.
import javax.persistence.*;
/**
*
* @author adm
*/
@Entity
@Table(name="bug")
public class Bug implements java.io.Serializable {
private Integer id_bug;
private String titulo;
private java.util.Date data;
private String texto;
/** Creates a new instance of Bug */
public Bug() {
}
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE)
@Column(name="id_bug")
public Integer getId_bug() {
return id_bug;
}
public void setId_bug(Integer id_bug) {
this.id_bug = id_bug;
}
@Column(name="titulo")
public String getTitulo() {
return titulo;
}
public void setTitulo(String titulo) {
this.titulo = titulo;
}
@Temporal(TemporalType.DATE)
@Column(name="data")
public java.util.Date getData() {
return data;
}
public void setData(java.util.Date data) {
this.data = data;
}
@Column(name="texto")
public String getTexto() {
return texto;
}
public void setTexto(String texto) {
this.texto = texto;
}
@Override
public String toString(){
return "ID: "+this.id_bug;
}
}
Agora vamos criar nossa classe BugService, onde está classe irá conter os métodos com as operações de insert, update, delete e query. Vamos olhar de perto nossa classe BugService na listagem 03.
package bugjpa;
import java.text.ParseException;import java.text.SimpleDateFormat;import
java.util.Arrays;import java.util.Date;import javax.persistence.*;import
java.util.Collection;
public class BugService {
private EntityManagerFactory factory;
/** Creates a new instance of BugService */
public BugService() {
factory = Persistence.createEntityManagerFactory("exemploPU");
}
private EntityManager getEntityManager() {
return factory.createEntityManager();
}
public void create(Bug bug) {
EntityManager em = getEntityManager();
try {
em.getTransaction().begin();
em.persist(bug);
em.getTransaction().commit();
} catch (Exception ex) {
ex.printStackTrace();
em.getTransaction().rollback();
} finally {
em.close();
}
}
public Bug findByPk( int pKey ) { EntityManager em = getEntityManager(); return
em.find(Bug.class, pKey);
}
public void remove( int id ){ EntityManager em = getEntityManager();
try {
em.getTransaction().begin();
Bug bug = em.find( Bug.class, id ); em.remove(bug);
em.getTransaction().commit();
} catch (Exception ex) {
try {
em.getTransaction().rollback();
} catch (Exception e) {
e.printStackTrace();
}
} finally {
em.close();
}
}
public Collection findAllBugs() {
EntityManager em = getEntityManager();
Query query = em.createQuery("SELECT object(o) FROM Bug as o");
return (Collection) query.getResultList();
}
}
Nossa aplicação deve conter o arquivo de persistence unit chamado persistence.xml para informarmos ao Persistence Context quais Classe de Entidades estamos usando e configurar os parâmetros de conexão. Na listagem 04, você pode ver o arquivo persistence.xml setado para utilizar o MySQL e informamos o nome da nossa classe de entidade. Este arquivo deve ficar em um diretório chamado META-INF localizado dentro da pasta bugjpa.
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=
"http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="exemploPU" transaction-type="RESOURCE_LOCAL">
<provider>racle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider
</provider>
<class>ugjpa.Bug</class>
<properties>
<property name="toplink.jdbc.url" value="jdbc:mysql://localhost:3306/bug"/>
<property name="toplink.jdbc.user" value="root"/>
<property name="toplink.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="toplink.jdbc.password" value="123456"/>
</properties>
</persistence-unit>
</persistence>
Agora, vamos criar uma classe cliente para utilizar nosso meio de utilizar alguns recursos do nosso banco de dados. Na listagem 05, segue o código da nossa classe Client.
package bugjpa;
import java.util.Collection;
public class BugClient {
public BugClient() {
}
public static void main( String args[] ){
System.out.println("Inserindo...");
BugService crud = new BugService();
java.util.Date date;
Bug bug = new Bug();
try {
date = BugBO.pegaData(); //Business Object
bug.setTitulo("Usando JPA em ambiente Java SE");
bug.setTexto("Muito show");
bug.setData(date);
crud.create( bug );
System.out.println("Cadastro Realizado com Sucesso!!!");
// Especificando o objeto a encotrar
bug = crud.findByPk(8);
System.out.println("Encontrado: " + bug.getTitulo());
// lista todos os bugs!!!
Collection bugs = crud.findAllBugs();
for (Bug b : bugs)
System.out.println("Bugs Encontrados: " + b.getTitulo());
} catch (Exception ex) {
ex.printStackTrace();
}
Vamos testar nossa aplicação via console, para obter os resultados esperados. Complile todas as classes e veja na Figura 1 como nossa classe Cliente se comporta ao executar algumas operações no DB.
Conclusão
Este artigo foi escrito com o intuito de mostrar como é simples, prático e muito eficaz a utilização de JPA em aplicações Java, e ainda em aplicações complexas o uso de JPA é com certeza fundamental para o aumento de produtividade no desenvolvimento do software. Existem formas ainda mais produtivas, quando, por exemplo, utilizamos o NetBeans IDE 5.5 que tem um recurso muito interessante de conectar no banco de dados, criar nossas classes de entidade e ainda a partir delas, criar as páginas JSF com telas de listagem com paginação, inserção, alteração remoção de objetos.