DAO com filtros dinânicos

3 respostas
A

Bom dia a todos
Já acompanho o GUJ a bastante tempo mas este é o meu primeiro post, então peço desculpas caso esteja postanto no forum errado ou fazendo qualquer outra bobagem sem querer…

Minha dúvida é a seguinte, e já pesquisei bastante e ainda não consegui chegar a uma conclusão,

Qual a forma mais elegante e correta para se trabalhar com uma consulta que possa ter diversos filtros ou nenhum, por exemplo imagine que temos uma tela de pesquisa de clientes e nesta tela posso utilizar diversos filtros(nome, idade, sexo, estado civil, cidade, ativo/inativo, …) conforme os filtros selecionados será preciso montar um filtro diferente para executar o select, ou ainda não passar nenhum filtro caso o usuário não selecione nenhum critério.

Diante deste cenário, qual a melhor forma de passar este filtro da View para o DAO?
Se eu montar uma string com o filtro na View e passar para o DAO estou colocando código sql onde não devia e não é viável ter um método para cada combinação de filtro no DAO,
Qual é a melhor solução para manter as boas práticas nesta situação?

Obrigado!

3 Respostas

C

A melhor forma de criar SQL dinâmico nesse caso vc quer ultizar filtros, é pensar numa lógica que ultiliza-se
"Cabeçalho, Corpo e Rodapé" onde o corpo será dinamico.
Acontece varios problemas aqui na empresa onde novatos não sabem fazer uma Procedure dinamica e acaba fazendo 900 linhas
pra uma consulta "ja peguei casos assim".. e onde tive que adaptar, pois no software demorava mais de 3 minutos pra realizar essa consulta..
é algo tragico.. acabei diminuindo com um sql dinamico para 90 linhas, pra voce ver..

Seria algo assim,

String sSQL = "SELECT * FROM TABELA WHERE NOME = 'X' "; //cabeçalho

IF (SELECIONOU FILTRO1 = TRUE) sSQL += " AND BETWEEN DATA1 = 01/01/2000 AND DATA2 = 01/02/2000"
IF (SELECIONOU FILTRO2 = TRUE) sSQL += " AND APELIDO = 'TESTE' "
IF (SELECIONOU FILTRO3 = TRUE) sSQL += " AND ATIVO = 'TRUE' "

sSQL += " ORDER BY ID ASC" //rodape

algo desse nipe..

J

Cria uma classe para o filtro com as propriedades para o mesmo, no request você recebe o objeto e passa para o DAO montar o SQL e setar named parameters (não concatene valores no SQL vindos do usuário) de acordo com as propriedades preenchidas. Ou ainda usar “OR”, devidamente isolado por condição, para checar se o parâmetro está preenchido com o objetivo de anular a condição. Se usasse Hibernate poderia usar Criteria, adicionando criterios conforme a propriedade do filtro preenchida.

B

Recomendo você criar um objeto como PessoaQuery, onde no teu DAO, ou qualquer outra classe que monte as SQLs, receba ele e faça a consulta, exemplo;

class PessoaDAO {

  List<Pessoa> consulta(PessaoQuery query) {

    // Onde gera a String de SQL ou Criteria com segurança. Otimiza se for capaz.
    String sql = geraConsulta(query);

    // Onde monta os PreparedStamements, ResultSets, JDBCTemplate, qualquer seja a tecnologia,
    // passando a sql e os argumentos, e executa a consulta. 
    return executaConsulta(sql, query);  
  }
}
Criado 13 de janeiro de 2013
Ultima resposta 13 de jan. de 2013
Respostas 3
Participantes 4