31
JPQL Marco A. S. Reis http:// marcoreis.net

JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

Embed Size (px)

Citation preview

Page 1: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

JPQLMarco A. S. Reishttp://marcoreis.net

Page 2: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

Agenda

Classes de infraestrutura (genéricas)

Data Access Object

Consultas

Parâmetros de consulta

Interceptadores

Page 3: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

DAOGenericoJPA

package org.comum.persistencia;

import java.lang.reflect.*;import java.util.*;

import javax.persistence.*;

@SuppressWarnings("unchecked")public class DAOGenericoJPA<T> { protected EntityManager em; private static EntityManagerFactory emf;

public DAOGenericoJPA(String pu) { if (emf == null) { emf = Persistence.createEntityManagerFactory(pu, new HashMap()); } em = emf.createEntityManager(); }

protected Class<T> getClasse() { Class<T> classe = null; ParameterizedType pt = (ParameterizedType) ((Class<?>) getClass()).getGenericSuperclass(); classe = (Class<T>) pt.getActualTypeArguments()[0]; return classe; }

Page 4: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

DAOGenericoJPA

public void inserir(T objeto) { em.getTransaction().begin(); em.persist(objeto); em.getTransaction().commit(); }

public void atualizar(T objeto) { em.getTransaction().begin(); em.merge(objeto); em.getTransaction().commit(); }

public T consultarPeloId(Long id) { return em.find(getClasse(), id); }

public List<T> consultarTodos() { String sql = "SELECT C FROM " + getClasse().getName() + " C "; return em.createQuery(sql).getResultList(); }

// A classe de entidade deve ter o findAll public List consultarTodosNamedQuery() { return em.createNamedQuery("findAll").getResultList(); }

public void excluir(T objeto) { em.getTransaction().begin(); em.remove(objeto); em.getTransaction().commit(); }}

Page 5: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

DAOConta

• Subclasse do DAOGenericoJPA. • Utiliza generics para especificar qual a

entidade.

Page 6: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

DAOCorrentista

Similar ao DAOConta.

Deve haver um DAO para cada classe de entidade.

Page 7: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

NamedQuery

Query estática que fica na própria classe de entidade.

Atualize a entidade adicionando um correntista.

Page 8: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

TesteDAOInsereConta

package org.financeiro.entidades.teste;

import javax.swing.*;import org.financeiro.entidades.*;import org.financeiro.persistencia.*;

public class TesteDAOInsereConta { public static void main(String[] args) { // DAOCorrentista daoCorrentista = new DAOCorrentista(); Correntista cliente = daoCorrentista.consultarPeloId(9L); // if (cliente != null) { // DAOConta daoConta = new DAOConta(); Conta conta = new Conta(); conta.setCorrentista(cliente); conta.setNumero("1234"); conta.setDigitoVerificador("5"); conta.setTipoDeConta(TipoDeConta.INVESTIMENTO); conta.setSaldoAtual(-1.0); // daoConta.inserir(conta); JOptionPane.showMessageDialog(null, "Conta cadastrada"); } else { // JOptionPane.showMessageDialog(null, "Cliente não cadastrado"); } }}

Page 9: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

TesteDAOConsultaConta

package org.financeiro.entidades.teste;

import java.util.*;

import org.financeiro.entidades.*;import org.financeiro.persistencia.*;

public class TesteDAOConsultaConta { public static void main(String[] args) { DAOConta dao = new DAOConta(); List<Conta> listaDeContas = dao.consultarTodos(); System.out.println("Lista de Contas\n"); for (Conta c : listaDeContas) { System.out.println("Conta ID: " + c.getId()); System.out.println("Numero: " + c.getNumero() + "-" + c.getDigitoVerificador()); System.out.println("Saldo: " + c.getSaldoAtual()); System.out.println("Correntista: " + c.getCorrentista().getNome()); System.out.println("----------------------"); } // }}

Page 10: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

TesteDAOConsultaContaDoCliente

package org.financeiro.entidades.teste;

import java.util.*;

import javax.swing.*;

import org.financeiro.entidades.*;import org.financeiro.persistencia.*;

public class TesteDAOConsultaContaDoCliente { public static void main(String[] args) { DAOConta dao = new DAOConta(); DAOCorrentista daoCorrentista = new DAOCorrentista(); Correntista cliente = daoCorrentista.consultarPeloId(9L); List<Conta> listaDeContas = dao.consultaContasDoCorrentista(cliente); if (listaDeContas.size() == 0) { JOptionPane.showMessageDialog(null, "Nenhuma conta do correntista"); } System.out.println("Lista de Contas\n"); for (Conta c : listaDeContas) { System.out.println("Conta ID: " + c.getId()); System.out.println("Numero: " + c.getNumero() + "-" + c.getDigitoVerificador()); System.out.println("Saldo: " + c.getSaldoAtual()); System.out.println("Correntista: " + c.getCorrentista().getNome()); System.out.println("----------------------"); } // }}

Page 11: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

DAOConta

package org.financeiro.persistencia;

import java.util.*;

import javax.persistence.*;

import org.comum.persistencia.*;import org.financeiro.entidades.*;

public class DAOConta extends DAOGenericoJPA<Conta> { // public DAOConta() { super("financeiro-pu"); }

public List<Conta> consultaContasDoCorrentista(Correntista c) { Query query = em .createQuery("SELECT C FROM Conta C WHERE C.correntista = ?"); query.setParameter(1, c); return query.getResultList(); }

public List<Conta> consultaContasSaldoNegativo() { Query query = em .createQuery("SELECT C FROM Conta C WHERE C.saldoAtual < 0"); return query.getResultList(); }}

Page 12: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

TesteDAOConsultaVermelho

package org.financeiro.entidades.teste;

import java.util.*;

import javax.swing.*;

import org.financeiro.entidades.*;import org.financeiro.persistencia.*;

public class TesteDAOConsultaVermelho { public static void main(String[] args) { DAOConta dao = new DAOConta(); List<Conta> listaDeContas = dao.consultaContasSaldoNegativo(); if (listaDeContas.size() == 0) { JOptionPane.showMessageDialog(null, "Nenhuma conta negativa"); } System.out.println("Lista de Contas\n"); for (Conta c : listaDeContas) { System.out.println("Conta ID: " + c.getId()); System.out.println("Numero: " + c.getNumero() + "-" + c.getDigitoVerificador()); System.out.println("Saldo: " + c.getSaldoAtual()); System.out.println("Correntista: " + c.getCorrentista().getNome()); System.out.println("----------------------"); } // }}

Page 13: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

TesteDAOConsultaContasDoCliente

package org.financeiro.entidades.teste;

import java.util.*;

import javax.swing.*;

import org.financeiro.entidades.*;import org.financeiro.persistencia.*;

public class TesteDAOConsultaContaDoCliente { public static void main(String[] args) { DAOConta dao = new DAOConta(); DAOCorrentista daoCorrentista = new DAOCorrentista(); Correntista cliente = daoCorrentista.consultarPeloId(9L); List<Conta> listaDeContas = dao.consultaContasDoCorrentista(cliente); if (listaDeContas.size() == 0) { JOptionPane.showMessageDialog(null, "Nenhuma conta do correntista"); } System.out.println("Lista de Contas\n"); for (Conta c : listaDeContas) { System.out.println("Conta ID: " + c.getId()); System.out.println("Numero: " + c.getNumero() + "-" + c.getDigitoVerificador()); System.out.println("Saldo: " + c.getSaldoAtual()); System.out.println("Correntista: " + c.getCorrentista().getNome()); System.out.println("----------------------"); } // }}

Page 14: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

Atividade

• Criar o DAOPessoa.

Page 15: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

Interceptadores

• Intercepta as principais operações e processa validações sobre os dados.– @PrePersist– @PostPersist– @PreUpdate– @PostUpdate– @PreRemove– @PostRemove– @PostLoad

Page 16: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

Interceptador em Conta

Na classe Conta, vamos criar um método interceptador.

@PostLoad

public void valida() {

if (saldoAtual == null) {

saldoAtual = 0.0;

}

}

Rodar novamente o TesteDAOConsultaConta e verificar o resultado.

Page 17: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

IdadeListener

package org.financeiro.entidades;

import java.util.*;

import javax.persistence.*;

public class IdadeListener { @PostLoad @PrePersist public void calculaIdade(Pessoa pessoa) { if (pessoa.getDataDeNascimento() == null) { pessoa.setIdade(-1); return; } Calendar nascimento = new GregorianCalendar(); nascimento.setTime(pessoa.getDataDeNascimento()); Calendar hoje = new GregorianCalendar(); hoje.setTime(new Date()); Integer idade = hoje.get(Calendar.YEAR) - nascimento.get(Calendar.YEAR); pessoa.setIdade(idade); }}

Page 18: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

Pessoapackage org.financeiro.entidades;

import java.util.*;

import javax.persistence.*;

@Entity@Inheritance(strategy = InheritanceType.JOINED)@EntityListeners({IdadeListener.class})public class Pessoa { private Long id; private String nome; private String endereco; private String telefone; @Temporal(TemporalType.DATE) private Date dataDeNascimento; @Transient private Integer idade;

@Id @GeneratedValue(strategy = GenerationType.IDENTITY) public Long getId() { return id; }

{…}

}

Page 19: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

TesteDAOInserePessoa

package org.financeiro.entidades.teste;

import java.text.*;import java.util.*;

import org.financeiro.entidades.*;import org.financeiro.persistencia.*;

public class TesteDAOInserePessoa { public static void main(String[] args) { DAOPessoa daoPessoa = new DAOPessoa(); // try { Pessoa p = new Pessoa(); p.setEndereco("Aguas Claras"); p.setNome("Jose"); p.setTelefone("3333-4444"); SimpleDateFormat formatador = new SimpleDateFormat("dd/MM/yyyy"); Date dataDeNascimento; dataDeNascimento = formatador.parse("06/04/1979"); p.setDataDeNascimento(dataDeNascimento); // daoPessoa.inserir(p); } catch (ParseException e) { e.printStackTrace(); } }}

Page 20: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

DAOPessoa

package org.financeiro.persistencia;

import java.util.*;

import javax.persistence.*;

import org.comum.persistencia.*;import org.financeiro.entidades.*;

public class DAOPessoa extends DAOGenericoJPA<Pessoa> { public DAOPessoa() { super("financeiro-pu"); }

public List<Pessoa> consultaPessoasPeloNomeParcial(String nomeParcial) { String sql = "SELECT P FROM Pessoa P WHERE P.nome like ?1"; Query query = em.createQuery(sql); query.setParameter(1, nomeParcial); return query.getResultList(); }}

Page 21: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

TesteDAOConsultaPessoaLike

package org.financeiro.entidades.teste;

import java.util.*;

import org.financeiro.entidades.*;import org.financeiro.persistencia.*;

public class TesteDAOConsultaPessoaLike { public static void main(String[] args) { DAOPessoa daoPessoa = new DAOPessoa(); List<Pessoa> lista = daoPessoa.consultaPessoasPeloNomeParcial("paulo%"); System.out.println("Lista de pessoas com nome like 'paulo' "); for (Pessoa p : lista) { System.out.println(p.getNome()); } }}

Page 22: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

Atividade

Mostrar todas as movimentações para um determinado período.

Mostrar as movimentações de uma conta específica para um determinado período.

Observação: antes de consultar os dados, vamos inserir várias movimentações para popular a tabela.

Page 23: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

Movimentacao

Acrescente o relacionamento entre Movimentacao e Conta.

Neste exemplo vemos uma NamedQuery para consultar as movimentações em um intervalo de datas.

Page 24: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

NamedQuery

Para acessar uma NamedQuery, utilizamos a sintaxe:em.createNamedQuery("nomeDaConsulta");

Os parâmetros podem ser declarados de duas formas:Parâmetro com nome:

• SELECT M FROM Movimentacao M WHERE M.data BETWEEN :dataInicial AND :dataFinal

Parâmetro indexado:

• SELECT M FROM Movimentacao M WHERE M.data BETWEEN ?1 AND ?2

Page 25: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

DAOMovimentacao

package org.financeiro.persistencia;

import java.util.*;import javax.persistence.*;import org.comum.persistencia.*;import org.financeiro.entidades.*;

public class DAOMovimentacao extends DAOGenericoJPA<Movimentacao> { public DAOMovimentacao() { super("financeiro-pu"); }

public List<Movimentacao> consultaMovimentacoesPelaData(Date dataInicial,Date dataFinal) { Query query = em.createNamedQuery("consultaMovimentacoesNoPeriodo"); query.setParameter("dataInicial", dataInicial); query.setParameter("dataFinal", dataFinal); return query.getResultList(); }}

Page 26: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

Inserindo dados na tabelapackage org.financeiro.entidades.teste;import java.math.*;import java.text.*;import java.util.*;import javax.swing.*;import org.financeiro.entidades.*;import org.financeiro.persistencia.*;

public class TesteDAOInsereMovimentacao { public static void main(String[] args) { try { // DAOConta daoConta = new DAOConta(); DAOMovimentacao daoMovimentacao = new DAOMovimentacao(); // Conta conta = daoConta.consultarPeloId(1L); if (conta == null) { JOptionPane.showMessageDialog(null, "Conta nao cadastrada"); return; } // Movimentacao pagamento = new Movimentacao(); // SimpleDateFormat formatador =new SimpleDateFormat("dd/MM/yyyy"); Date dataDePagamento = formatador.parse("26/08/2011"); // pagamento.setConta(conta); pagamento.setData(dataDePagamento); pagamento.setDescricao("PAGAMENTO DE CONTA DE TELEFONE"); pagamento.setTipoDeMovimentacao(TipoDeMovimentacao.DEBITO); pagamento.setValor(new BigDecimal(399.99)); // daoMovimentacao.inserir(pagamento); JOptionPane.showMessageDialog(null, "Movimentacao efetuada"); } catch (Exception e) { e.printStackTrace(); } }}

Page 27: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

Consultando as movimentações do períodopackage org.financeiro.entidades.teste;

import java.text.*;import java.util.*;

import org.financeiro.entidades.*;import org.financeiro.persistencia.*;

public class TesteDAOConsultaMovimentacoes { public static void main(String[] args) { try { DAOMovimentacao dao = new DAOMovimentacao(); SimpleDateFormat formatador = new SimpleDateFormat("dd/MM/yyyy"); Date dataInicial = formatador.parse("27/08/2011"); Date dataFinal = formatador.parse("27/08/2011"); List<Movimentacao> lista = dao.consultaMovimentacoesPelaData(dataInicial,dataFinal); // System.out.println("---------------"); for (Movimentacao m : lista) { System.out.println("Cliente: "+ m.getConta().getCorrentista().getNome()); System.out.println("Movimentacao: " + m.getDescricao()); System.out.println("Valor: " + m.getValor()); System.out.println("xxxxxxxxxxxxxxx"); } } catch (Exception e) { e.printStackTrace(); } }}

Page 28: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

Movimentacao

Podemos ter múltiplas consultas, conforme o exemplo abaixo, com a anotação @NamedQueries.

Page 29: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

DAOMovimentacao

O retorno da consulta será o total no período.

Em função disso, o tipo de retorno deve ser BigDecimal, que é o tipo de dado da coluna valor de Movimentacao.

Adicione o bloco de código abaixo em DAOMovimentacao

public BigDecimal consultaTotalNoPeriodo(Date dataInicial, Date dataFinal) { Query query = em.createNamedQuery("consultaTotalNoPeriodo"); query.setParameter("dataInicial", dataInicial); query.setParameter("dataFinal", dataFinal); return (BigDecimal) query.getSingleResult(); }

Page 30: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

Consulta total no período

package org.financeiro.entidades.teste;

import java.math.*;import java.text.*;import java.util.*;

import javax.swing.*;

import org.financeiro.persistencia.*;

public class TesteDAOConsultaTotalMovimentacoes { public static void main(String[] args) { try { DAOMovimentacao dao = new DAOMovimentacao(); SimpleDateFormat formatador = new SimpleDateFormat("dd/MM/yyyy"); Date dataInicial = formatador.parse("24/08/2011"); Date dataFinal = formatador.parse("26/08/2011"); BigDecimal total = dao.consultaTotalNoPeriodo(dataInicial, dataFinal); // JOptionPane.showMessageDialog(null, "Total no Período: " + total); } catch (Exception e) { e.printStackTrace(); } }}

Page 31: JPQL Marco A. S. Reis . Agenda Classes de infraestrutura (genéricas) Data Access Object Consultas Parâmetros de consulta Interceptadores

Atividade

Mostrar um relatório com todas as pessoas que nasceram em um determinado período, com suas repectivas idades.

Crie um interceptador que não permita a inserção de valores nulos para o valor do saldo atual da Conta.

Mostrar um relatório com as movimentações de um correntista, bem como o total movimentado por período.