Upload
internet
View
110
Download
4
Embed Size (px)
Citation preview
JPQLMarco A. S. Reishttp://marcoreis.net
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; }
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(); }}
DAOConta
• Subclasse do DAOGenericoJPA. • Utiliza generics para especificar qual a
entidade.
DAOCorrentista
Similar ao DAOConta.
Deve haver um DAO para cada classe de entidade.
NamedQuery
Query estática que fica na própria classe de entidade.
Atualize a entidade adicionando um correntista.
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"); } }}
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("----------------------"); } // }}
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("----------------------"); } // }}
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(); }}
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("----------------------"); } // }}
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("----------------------"); } // }}
Atividade
• Criar o DAOPessoa.
Interceptadores
• Intercepta as principais operações e processa validações sobre os dados.– @PrePersist– @PostPersist– @PreUpdate– @PostUpdate– @PreRemove– @PostRemove– @PostLoad
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.
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); }}
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; }
{…}
}
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(); } }}
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(); }}
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()); } }}
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.
Movimentacao
Acrescente o relacionamento entre Movimentacao e Conta.
Neste exemplo vemos uma NamedQuery para consultar as movimentações em um intervalo de datas.
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
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(); }}
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(); } }}
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(); } }}
Movimentacao
Podemos ter múltiplas consultas, conforme o exemplo abaixo, com a anotação @NamedQueries.
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(); }
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(); } }}
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.