Aula JPA
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

Aula JPA

  • 626 views
Uploaded on

Apostila da aula de JPA, cobrindo os seguintes tópicos: ...

Apostila da aula de JPA, cobrindo os seguintes tópicos:
- jpa
- hibernate
- many-to-one
- mapeamento objeto relacional
- entity manager
- junit
- namedquery
- query

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
626
On Slideshare
620
From Embeds
6
Number of Embeds
2

Actions

Shares
Downloads
21
Comments
0
Likes
1

Embeds 6

http://www.slideee.com 5
http://www.linkedin.com 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Java Persistence API JPA Marco Reis Software Architect http://marcoreis.net
  • 2. Agenda • Mapeamento objeto-relacional. • JPA x Hibernate. • Criação das tabelas. • Executar comandos de inclusão, alteração, exclusão e consulta.
  • 3. Código-fonte • O projeto de exemplo com o código-fonte está disponível em: – https://github.com/masreis/e-commerce
  • 4. Mapeamento objeto-relacional • JPA é um modelo de persistência baseado em POJO. • Java é utilizada em ambientes corporativos, com grandes bancos de dados. • Agiliza o desenvolvimento, já que não precisamos escrever comandos SQL. • Fácil de mudar de banco de dados, caso necessário.
  • 5. JPA x Hibernate • JPA é a especificação da Oracle para mapenamento objeto-relacional. • Hibernate apresentava uma maneira mais elegante de trabalhar com a persistência do que o J2EE.
  • 6. Arquivo de configuração • O arquivo persistence.xml contém os parâmetros de configuração para acesso ao banco de dados e deve estar no diretório META-INF. • Persistence unit name (e-commerce-pu): indica os parâmetros de acesso à base de dados. • transaction-type: RESOURCE_LOCAL para servidor web e JTA para servidor de aplicação. • Provider: qualquer implementação do JPA. Pode ser o Hibernate, OpenJPA ou EclipseLink, que é o produto oficial da Oracle.
  • 7. persistence.xml <?xml version="1.0" encoding="UTF-8"?> <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_2_0.xsd" version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"> <persistence-unit name="e-commerce-pu" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" /> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver" /> <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:file:e-commerce/db;shutdown=true;hsqldb.write_delay=false;" /> <property name="javax.persistence.jdbc.user" value="SA" /> <property name="javax.persistence.jdbc.password" value="" /> </properties> </persistence-unit> </persistence>
  • 8. Entidades • Com JPA podemos mapear as classes de entidade diretamente para o banco de dados. • Vamos considerar as seguintes classes: – Usuario – Cliente – Produto – Categoria • As anotações do JPA estão no pacote javax.persistence.
  • 9. Classe Usuario package net.marcoreis.ecommerce.entidades; import java.util.Date; public class Usuario { private Long id; private String email; private String nome; private Date ultimoLogin; {sets e gets} }
  • 10. Classe Usuario persistente @Entity public class Usuario { @Id @GeneratedValue private Long id; private String email; private String nome; private Date ultimoLogin; } • Para persistir uma classe usando JPA é necessário adicionar ao menos as seguintes anotações: – @Entity: a classe será armazenada em uma tabela. – @Id: campo da chave-primária. – @GeneratedValue: a chave-primária será gerada automaticamente.
  • 11. Teste unitário com JUnit • As funcionalidades serão testadas com o Junit. • Cada funcionalidade será validada com um teste unitário. • As classes de teste vão ficar no pacote: – net.marcoreis.ecommerce.teste • As classes do JUnit estão em org.junit. • Para rodar um teste, vá no menu Run-Run as-JUnit test. • Adicione a dependência do Maven no pom.xml. • Utilize o @Before e @After para inicializar e finalizar variáveis. Quando o teste envolver inclusão, alteração ou exclusão de registros, é obrigatório o begin() e commit(). <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency>
  • 12. Inserindo registros public class TesteInsereUsuario { private EntityManager em; @Before public void inicializar() { em = JPAUtil.getInstance().getEntityManager(); em.getTransaction().begin(); } @After public void finalizar() { em.getTransaction().commit(); em.close(); } @Test public void inserirUsuario() { Usuario usuario = new Usuario(); usuario.setEmail("ma@marcoreis.net"); usuario.setNome("Marco Reis"); Date data = new Date(); usuario.setUltimoLogin(data); em.persist(usuario); } }
  • 13. Consulta registros gravados • Para consultar os registros já gravados vamos usar uma Query ou uma NamedQuery. • A NamedQuery fica na classe persistente, enquanto que a Query pode estar em qualquer outra classe do sistema. • Os parâmetros podem usar as seguintes formas: – :nomeParametro1, :nomeParametro2. – ?1, ?2, ?3. @Entity @NamedQuery(name = "usuario.consultaAcessoDia", query = "from Usuario where cast(ultimoLogin as date) = :data") public class Usuario { @Id @GeneratedValue private Long id; private String email; private String nome; private Date ultimoLogin; }
  • 14. NamedQuery • Adicione uma NamedQuery em Usuario. • O cast é necessário porque a data é armazenada em timestamp, e a consulta deve considerar somente a data, ignorando a hora/minuto/segundo. @Entity @NamedQuery(name = "usuario.consultaAcessoDia", query = "from Usuario where cast(ultimoLogin as date) = :data") public class Usuario { @Id @GeneratedValue private Long id; private String email; private String nome; private Date ultimoLogin; }
  • 15. Consulta registros gravados • Em seguida, vamos criar o teste unitário para verificar os usuários cadastrados. public class TesteConsultaUsuarios { private EntityManager em; @Before public void inicializar() { em = JPAUtil.getInstance().getEntityManager(); } @After public void finalizar() { em.close(); } }
  • 16. Consulta registros gravados • O primeiro teste unitário utiliza uma Query, retornando todos os usuários cadastrados. @Test public void consultaTodosUsuarios() { String queryJPA = "from Usuario"; Query query = em.createQuery(queryJPA); List<Usuario> usuarios = query.getResultList(); for (Usuario usuario : usuarios) { System.out.println("Nome: " + usuario.getNome()); } }
  • 17. Consulta registros gravados • O teste unitário abaixo acessa a NamedQuery e passa um parâmetro, mostrando apenas os registros que têm a data de hoje. @Test public void consultaUsuriosAcessoDia() { em = JPAUtil.getInstance().getEntityManager(); Query query = em.createNamedQuery("usuario.consultaAcessoDia"); query.setParameter("data", new Date()); List<Usuario> usuarios = query.getResultList(); for (Usuario usuario : usuarios) { System.out.println("Nome/ultimo login: " + usuario.getNome() + " - " + usuario.getUltimoLogin()); } }
  • 18. Alterando registros gravados • Para os testes abaixo crie a classe TesteAlteraUsuario. • Para alterar um registro, primeiro faça uma consulta pelo ID. Dessa forma, o objeto será gerenciado pelo EntityManager e poderá ser atualizado. @Test public void alterarUsuario() { Long id = 2l; Usuario usuario = em.find(Usuario.class, id); Assert.assertNotNull("Usuario não cadastrado", usuario); usuario.setEmail("diego@lucas.net"); usuario.setNome("Diego Lucas"); Date data = new Date(); usuario.setUltimoLogin(data); em.persist(usuario); }
  • 19. Removendo registros gravados • Para os testes abaixo crie a classe TesteRemoveUsuario. • A exclusão deve ser feita após uma consulta pelo ID, seguindo a mesma ideia da alteração. @Test public void removerUsuario() { Long id = 5l; Usuario usuario = em.find(Usuario.class, id); Assert.assertNotNull("Usuario não cadastrado", usuario); em.remove(usuario); }
  • 20. Herança • Há 3 estratégias de herança no JPA: – JOINED: uma tabela para cada entidade, não repete os campos. – SINGLE_TABLE: apenas uma tabela para todas as classes. – TABLE_PER_CLASS: uma tabela para cada classe, repetindo todos os campos.
  • 21. Classe Cliente • Para mostrar o funcionamento da herança no JPA, crie a classe Cliente, subclasse de Usuario. • Não é necessário redefinir o Id, que já está na superclasse. @Entity public class Cliente extends Usuario { @Column(unique = true, nullable = false) private String cpfCnpj; {sets e gets} }
  • 22. Teste do Cliente • Agora, crie a classe TesteInsereCliente para testar a nova entidade. • Não se esqueça dos métodos de inicialização e finalização. • A título de teste, comente a linha do cpfCnpj e veja o resultado. @Test public void inserirCliente() { Cliente cliente = new Cliente(); cliente.setEmail("jose@oracle.com"); cliente.setNome("Jose Carlos"); // cliente.setCpfCnpj("123456"); em.persist(cliente); Assert.assertTrue("Cliente gravado com sucesso", cliente.getId() > 0); }
  • 23. Como funciona • Acompanhando o log do Hibernate podemos verificar que foram incluídos 2 registros, um na tabela Usuario e outro na tabela Cliente. • Isso porque a estratégia de herança selecionada foi JOINED. Hibernate: insert into Usuario (id, email, nome, ultimoLogin) values (default, ?, ?, ?) Hibernate: insert into Cliente (cpfCnpj, id) values (?, ?)
  • 24. Atividade • Crie as classes de teste Categoria: – Inclusão. – Alteração. – Exclusão. – Consulta todas as categorias.
  • 25. Relacionamentos • O JPA tem as seguintes multiplicidades, seguindo o modelo relacional: – many-to-one. – one-to-one. – one-to-many. – many-to-many.
  • 26. Many-to-one • O relacionamento many-to-one está presente na classe produto. • Segundo o modelo, cada produto deve ter uma categoria. public class Produto { @Id @GeneratedValue private Long id; @ManyToOne private Categoria categoria; private String nome; private String descricao; private String especificacaoLoja; @Lob private byte[] especificacaoFabricante; private Double preco; }
  • 27. Inserindo produtos • Para inserir um produto precisamos escolher uma categoria válida. • O primeiro passo é pesquisar uma categoria já cadastrada. • Em seguida podemos preencher os demais atributos e persistir a entidade. @Test public void inserirProduto() { Long idCategoria = 12l; Categoria categoria = em.find(Categoria.class, idCategoria); Assert.assertNotNull("Categoria não cadastrada", categoria); Produto produto = new Produto(); produto.setCategoria(categoria); produto.setDescricao("Colcha para cama de solteiro 120cm x 210cm"); produto.setNome("Colcha para cama de solteiro"); produto.setPreco(150.00); em.persist(produto); }
  • 28. Consultando produtos • Para os exemplos seguintes crie a classe TesteConsultaProdutos. • O primeiro teste, consultarTodasCategorias, segue o mesmo princípio das demais. @Test public void consultarTodosProdutos() { System.out.println("Consultar todos os produtos"); List<Produto> produtos = em.createQuery("from Produto").getResultList(); for (Produto p : produtos) { System.out.println(p.getId() + " - " + p.getNome()); } }
  • 29. Consultando produtos pela categoria • O exemplo abaixo mostra os produtos de uma categoria específica. • Este teste usa uma Query, mas poderia ser facilmente adaptado para utilizar NamedQuery. @Test public void consultarProdutosPelaCategoria() { System.out.println("Consultar produtos pela categoria"); Long idCategoria = 12l; List<Produto> produtos = em .createQuery("from Produto where categoria.id = ?1") .setParameter(1, idCategoria ).getResultList(); for (Produto p : produtos) { System.out.println(p.getId() + " - " + p.getNome()); } }
  • 30. Consultando quantidades • Adicione as NamedQueries abaixo em Produto e o teste na classe TesteConsultaProdutos. @NamedQueries({ @NamedQuery(name = "produto.consultaTotalPorCategoria", query = "select count(p) from Produto p where categoria.id = :idCategoria"), @NamedQuery(name = "produto.consultaPorIntervaloPreco", query = "from Produto where preco >= ?1 and preco <= ?2") }) @Test public void consultarTotalProdutoPelaCategoria() { System.out.println("Consultar total de produtos pela categoria"); Query query = em.createNamedQuery("produto.consultaTotalPorCategoria"); Long idCategoria = 12l; query.setParameter("idCategoria", idCategoria); Object resultado = query.getSingleResult(); System.out.println("Total de produtos na categoria: " + resultado); }
  • 31. Atividades • Criar o teste unitário para a NamedQuery 'produto.consultaPorIntervaloPreco' na classe TesteConsultaProdutos. • Criar as classes abaixo, com seus relacionamentos, atributos e testes unitários. – Venda (id, data, cliente). – Item (id, produto, quantidade, valorUnitario, venda).
  • 32. Referência • http://docs.oracle.com/javaee/6/tutorial/