Versão ALPHA! Este artigo está em versão 'Alpha' e, portanto, não foi ainda revisado corretamente

Implementando Consultas: Consultas

Introdução

Para realizarmos uma consulta em um banco de dados, precisamos de métodos que sejam capazes de enviar a query (escrita na linguagem SQL) ao banco de dados. Algumas classes específicas são responsáveis por executar esta tarefa.

Antes de iniciar

Este item exige conhecimentos sobre:

  • Interface
  • Linguagem SQL

Implementação

Conforme o artigo anterior, as consultas precisam ser criadas para que o teste realmente funcione. Neste momento, já temos a classe de teste TesteDeConsultaDeLivroe a interface ConsultaDeLivroDTO. Criaremos o método e as classes privadas em ConsultaDeLivro.

Implementando a classe ConsultaDeLivro

A classe ConsultaDeLivro, neste momento, possui apenas o método consulta.

public List<ConsultaDeLivroDTO> list(RequestWrapper wrapper) {
  return null;
}

Crie o construtor parametrizado Provider do pacote com.google.inject junto a interface NativeSql do pacote br.com.objectos.comuns.relational.jdbc.

private final Provider<NativeSql> sqlProvider;
@Inject public ConsultaDeLivro(Provider sqlProvider) {
  this.sqlProvider = sqlProvider;
  	}

Crie uma classe privada DTO. Esta classe é um construtor que atribue os valores obtidos em cada resultSet (iremos criá-lo posteriormente) à uma variável de instância. Só assim o objeto ConsultaDeLivroDTO poderá ser instanciado com os valores desejados para o teste.

private static class DTO implements ConsultaDeLivroDTO {

  private final String titulo;
  private final int localizacao;
  private final String autoPrincipal;
  private final LocalDate publicacao;

  public DTO(ConsultaDeLivroDTO construtor) {
    this.titulo = construtor.getTitulo();
    this.localizacao = construtor.getLocalizacao();
    this.autoPrincipal = construtor.getAutorPrincipal();
    this.publicacao = construtor.getPublicacao();
  }

  @Override
  public String getTitulo() {
    return titulo;
  }

  @Override
  public int getLocalizacao() {
    return localizacao;
  }
    
  @Override
  public String getAutorPrincipal() {
    return autoPrincipal;
  }
    
  @Override
  public LocalDate getPublicacao() {
    return publicacao;
  }

}

Sempre utilize os atalhos Ctrl + 1 (para implementar os métodos e criar as variáveis), Ctrl + 2 seguido de L (para os getters do construtor) e Ctrl + espaço (para auto-completar o nome de variáveis e métodos).

Crie um Loader que define as colunas que serão consultadas através do ResultSetWrapper e também o método novaInstancia() do Construtor para criar um objeto com os valores da consulta.

Lembre-se: É necessário escrever o nome da tabela seguido da coluna para evitar futuros problemas na execução da query. Isto é comum quando adicionamos outras entidades nas consultas, por exemplo, ALUNO.ID e LIVRO.ID. Desta forma, o ID fica explícito a quem ele pertence.

private class Loader implements ConsultaDeLivroDTO, Construtor<ConsultaDeLivroDTO> {

  private final ResultSetWrapper rs;

  public Loader(ResultSetWrapper rs) {
    this.rs = rs;
  }
    
  @Override
  public ConsultaDeLivroDTO novaInstancia() {
    return new DTO(this);
  }

  @Override
  public String getTitulo() {
    return rs.getString("LIVRO.TITULO");
  }
    
  @Override
  public int getLocalizacao() {
    return rs.getInt("LIVRO.LOCALIZACAO");
  }
    
  @Override
  public String getAutorPrincipal() {
    return rs.getString("LIVRO.AUTO_PRINCIPAL");
  }
    
  @Override
  public LocalDate getPublicacao() {
    return rs.getLocalDate("LIVRO.PUBLICACAO");
  }
    
}      	

Crie a classe privada DTOLoader. Esta classe possui um método que instancia um Loader já com os dados populados em um objeto ConsultaDeLivroDTO retornando-o no fim da execução do método novaInstancia().

private class DTOLoader implements ResultSetLoader<ConsultaDeLivroDTO> {
  @Override
  public ConsultaDeLivroDTO load(ResultSet resultSet) throws SQLException {
    ResultSetWrapper rs = new ResultSetWrapper(resultSet);
    return new Loader(rs).novaInstancia();
  }
}

Por fim, escreva a query nos métodos add() e invoque o método .andLoadWith(new DTOLoader())

public List<ConsultaDeLivroDTO> list(RequestWrapper wrapper) {
  Page page = wrapper.getPage();
  Integer localizacao = wrapper.integerParam("localizacao");
  
  return sqlProvider.get()
      
      .add("select *")
      
      .add("from BIBLIOTECA.LIVRO as LIVRO")
      
      .add("where 1 = 1")
      .addIf("and LIVRO.LOCALIZACAO = ?").paramNotNull(localizacao)
      
      .add("order by")
      .add("LIVRO.TITULO")
      
      .andLoadWith(new DTOLoader())
      
      .listPage(page);
}

A linha .addIf("and LIVRO.LOCALIZACAO = ?").paramNotNull(localizacao) será executada somente se o valor de localizacao não for nulo, ou seja, somente quando há o método de teste de filtro e quando ele for executado (se existir). Quanto a cláusula where 1 = 1, foi definido desta forma para evitar erros na execução da query como na sintaxe a seguir:

.add("select *")

.add("from BIBLIOTECA.LIVRO as LIVRO")

.add("where LIVRO.TITULO = ?").param(titulo)
.addIf("and LIVRO.LOCALIZACAO = ?").paramNotNull(localizacao)

Se a variável titulo fosse nula, a query estaria errada:

select * from BIBLIOTECA.LIVRO as LIVRO and LIVRO.LOCALIZACAO = 123

Nota: Semelhante aos getters do ResultSet, indique a tabela e a coluna na query LIVRO.TITULO, talvez futuramente você precise adicionar uma outra tabela (usando um join por exemplo).

E por fim, se não tivessemos um filtro este método ficaria assim:

public List<ConsultaDeLivroDTO> list(RequestWrapper wrapper) {
  Page page = wrapper.getPage();
  
  return sqlProvider.get()
      
      .add("select *")
      
      .add("from BIBLIOTECA.LIVRO as LIVRO")
      
      .add("order by")
      .add("LIVRO.TITULO")
      
      .andLoadWith(new DTOLoader())
      
      .listPage(page);
}	

Nota: A sintaxe SQL é descrita em forma de String.

Execute o teste na classe TesteDeConsultaDeLivro e verifique os resultados obtidos!

Para mais informações acesse os códigos nos links abaixo:

ConsultaDeLivro.java
ConsultaDeLivroDTO.java

Retornar aos Procedimentos! Voltar!
Leia mais uma vez! Revisar!


 
 

objectos, Fábrica de Software LTDA

  • R. Demóstenes, 627. cj 123
  • 04614-013 - Campo Belo
  • São Paulo - SP - Brasil
  • +55 11 5093-8640
  • +55 11 2359-8699
  • contato@objectos.com.br