• Skip to primary navigation
  • Skip to content

Mauda

IT, Java and Music

Graduação   SCJP   Mestrado
  • Apresentação
  • Certificação Java
  • JPA
    • Exceptions
  • JSF
  • Versionamento
  • Contato

SQL – Dicas para Organizar um método de busca com Filtros

September 14, 2015 by Mauda Leave a Comment

Conteúdo do Post:
  1. Definição de Filtro
  2. Exemplo de método de busca por filtros – padrão JDBC
  3. Campos de um Filtro x Parâmetros de um método
  4. Utilização de classes da Camada Model
  5. Utilização de classes Data Transfer Object
  6. Removendo o condicional para o WHERE e AND
  7. Utilizando um Map para os parâmetros
  8. finnaly{

Olá Pessoal, tudo bom?

Nessa semana iremos falar sobre a organização de um método de busca com filtros, ou seja, em um filtro que eu possuo restrições variáveis. Existe uma dificuldade muitas vezes de realizar a organização destes filtros, pois precisamos inserir muitos condicionais, IFs, para atender a necessidade.

Dessa forma estarei mostrando algumas dicas de como melhorar a organização de seu código.

Definição de Filtro

Um filtro é uma estrutura que nos permite inserir uma ou mais informações sobre um determinado assunto e realizar uma pesquisa deste. O exemplo mais clássico de um filtro é o Google, a Figura 01 exibe uma animação de uma busca utilizando o Google:

Figura 01 – Animação de uma pesquisa com o Google – Credito Google

 

No caso de uma busca do Google, existe apenas 1 filtro. Mas nem todos os sistemas conseguem estabelecer telas que possuam apenas um campo de filtro, por exemplo a tela exibida na Figura 02, mostra uma área com vários campos que podem ser utilizados para buscas:

Figura 02 – Exemplo de uma tela com vários filtros de pesquisa -Crédito: https://mscblogs.blob.core.windows.net

Repare que existem diversos filtros como ID, que representa a identificação da Categoria, o Name, que representa o nome da categoria, Created User, que criou a categoria e por fim a Created Date, que representa a data de criação no banco de dados daquela categoria. Nessa tela você pode pesquisar não inserindo nenhum campo, todos os campos ou uma mescla destas opções.

Exemplo de método de busca por filtros – padrão JDBC

Uma das formas mais simples de criar métodos de busca é inserir todos os campos de um filtro como parâmetros desse método. Vamos supor a seguinte classe Endereco, conforme mostra a Figura 03:

Figura 03 – Classe Endereco – Representação UML

O código desta classe está representado abaixo:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
public class Endereco {
private Long id;
private String rua;
private Integer numero;
private String complemento;
private String bairro;
private String cidade;
private String estado;
private String pais;
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getRua() {
return this.rua;
}
public void setRua(String rua) {
this.rua = rua;
}
public Integer getNumero() {
return this.numero;
}
public void setNumero(Integer numero) {
this.numero = numero;
}
public String getComplemento() {
return this.complemento;
}
public void setComplemento(String complemento) {
this.complemento = complemento;
}
public String getBairro() {
return this.bairro;
}
public void setBairro(String bairro) {
this.bairro = bairro;
}
public String getCidade() {
return this.cidade;
}
public void setCidade(String cidade) {
this.cidade = cidade;
}
public String getEstado() {
return this.estado;
}
public void setEstado(String estado) {
this.estado = estado;
}
public String getPais() {
return this.pais;
}
public void setPais(String pais) {
this.pais = pais;
}
}

 

Vamos definir um método de busca, no padrão JDBC, para todos os atributos deste método:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
//Imports necessarios.....
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
 
//..... definicao da classe e outras coisas
 
    public List<Endereco> findByFilter(String rua, Integer numero, String complemento, String bairro, String cidade, String estado, String pais){
        Connection c = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            boolean whereAdd = false;
 
            //definicao do SQL inicial
            StringBuilder sb = new StringBuilder("SELECT * FROM TB_ENDERECO as end ");
 
            //Campo rua
            if(rua != null){
                if(!whereAdd){
                    sb.append(" WHERE ");
                    whereAdd = true;
                }
                sb.append(" end.rua like ? ");
            }//fim do campo rua
 
            //Campo numero
            if(numero != null){
                if(!whereAdd){
                    sb.append(" WHERE ");
                    whereAdd = true;
                } else {
                    sb.append(" AND ");
                }
                sb.append(" end.numero = ? ");
            }//fim do campo numero
 
            //Campo complemento
            if(complemento != null){
                if(!whereAdd){
                    sb.append(" WHERE ");
                    whereAdd = true;
                } else {
                    sb.append(" AND ");
                }
                sb.append(" end.complemento like ? ");
            }//fim do campo complemento
 
            //Campo bairro
            if(bairro != null){
                if(!whereAdd){
                    sb.append(" WHERE ");
                    whereAdd = true;
                } else {
                    sb.append(" AND ");
                }
                sb.append(" end.bairro like ? ");
            }//fim do campo bairro
 
            //Campo cidade
            if(cidade != null){
                if(!whereAdd){
                    sb.append(" WHERE ");
                    whereAdd = true;
                } else {
                    sb.append(" AND ");
                }
                sb.append(" end.cidade like ? ");
            }//fim do campo cidade
 
            //Campo estado
            if(estado != null){
                if(!whereAdd){
                    sb.append(" WHERE ");
                    whereAdd = true;
                } else {
                    sb.append(" AND ");
                }
                sb.append(" end.estado like ? ");
            }//fim do campo estado
 
            //Campo pais
            if(pais != null){
                if(!whereAdd){
                    sb.append(" WHERE ");
                    whereAdd = true;
                } else {
                    sb.append(" AND ");
                }
                sb.append(" end.pais like ? ");
            }//fim do campo pais
 
            //obtem a instancia da classe Connection
            c = Conexao.getConnection();
            ps = c.prepareStatement(sb.toString());
            int pos = 0;
 
            //Campo rua
            if(rua != null){
                ps.setObject(pos++, "%" + rua + "%");
            }//fim do campo rua
 
            //Campo numero
            if(numero != null){
                ps.setObject(pos++, numero);
            }//fim do campo numero
 
            //Campo complemento
            if(complemento != null){
                ps.setObject(pos++, "%" + complemento + "%");
            }//fim do campo complemento
 
            //Campo bairro
            if(bairro != null){
                ps.setObject(pos++, "%" + bairro + "%");
            }//fim do campo bairro
 
            //Campo cidade
            if(cidade != null){
                ps.setObject(pos++, "%" + cidade + "%");
            }//fim do campo cidade
 
            //Campo estado
            if(estado != null){
                ps.setObject(pos++, "%" + estado + "%");
            }//fim do campo estado
 
            //Campo pais
            if(pais != null){
                ps.setObject(pos++, "%" + pais + "%");
            }//fim do campo pais
 
            rs = ps.executeQuery();
            List<Endereco> enderecos = new ArrayList<Endereco>();
            while(rs.next()){
                Endereco endereco = new Endereco();
                endereco.setBairro(rs.getString("BAIRRO"));
                endereco.setCidade(rs.getString("CIDADE"));
                endereco.setComplemento(rs.getString("COMPLEMENTO"));
                endereco.setEstado(rs.getString("ESTADO"));
                endereco.setId(rs.getLong("ID"));
                endereco.setNumero(rs.getInt("NUMERO"));
                endereco.setPais(rs.getString("PAIS"));
                endereco.setRua(rs.getString("RUA"));
                enderecos.add(endereco);
            }
            return enderecos;
        } catch (SQLException e) {
            e.printStackTrace();
            throw e;
        } finally {
            //Fecha a conexao de todos os recursos do JDBC
            Conexao.close(rs, ps, c);
        }
    }

 

Esse método possui mais de 100 linhas, tornando a sua leitura mais complexa. Será que é possível organizá-lo de uma maneira a tornar mais fácil sua leitura? Sim é possível! Vamos analisar alguns pontos neste post e continuaremos a analisar nos próximos posts.

Campos de um Filtro x Parâmetros de um método

No caso do exemplo acima existem ao todo 7 parâmetros que representam o filtro de busca de uma tela de pesquisa de endereços. Assim, todos os campos que estão presentes no filtro são adicionados como parâmetros do método.

Isso é uma boa prática? Caso seja necessário adicionar mais campos no filtro de busca será necessário mexer nos parâmetros do método? Existe algum problema relacionado a isso?

Respondendo a primeira pergunta, isso não é uma boa prática, pois se a tela de pesquisa conter mais de 10, 15 campos, será necessário você adicionar 10, 15 parâmetros no seu método. Além disso, pode ser que esse método de busca seja utilizado em outras partes do sistema (ou talvez outros sistemas!), assim realizar uma mudança em sua assinatura, adicionando novos parâmetros, pode exigir mudanças de outros desenvolvedores no código, o que ocasiona retrabalho e gasto de tempo de projeto em correção de bugs.

Utilização de classes da Camada Model

Uma das formas de evitar que existam muitos parâmetros é utilizar a própria classe model base como Filtro. Assim, no método de exemplo, ao invés de passarmos 7 parâmetros, poderíamos passar apenas 1, uma instância de Endereco, que naturalmente já contém todos os campos de filtros, conforme mostra o código abaixo:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
//Imports necessarios.....
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
 
//..... definicao da classe e outras coisas
 
    public List<Endereco> findByFilter(Endereco endereco) {
        Connection c = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            boolean whereAdd = false;
 
            // definicao do SQL inicial
            StringBuilder sb = new StringBuilder("SELECT * FROM TB_ENDERECO as end ");
 
            // Campo rua
            if (endereco.getRua() != null) {
                if (!whereAdd) {
                    sb.append(" WHERE ");
                    whereAdd = true;
                }
                sb.append(" end.rua like ? ");
            } // fim do campo rua
 
            // Campo numero
            if (endereco.getNumero() != null) {
                if (!whereAdd) {
                    sb.append(" WHERE ");
                    whereAdd = true;
                } else {
                    sb.append(" AND ");
                }
                sb.append(" end.numero = ? ");
            } // fim do campo numero
 
            // Campo complemento
            if (endereco.getComplemento() != null) {
                if (!whereAdd) {
                    sb.append(" WHERE ");
                    whereAdd = true;
                } else {
                    sb.append(" AND ");
                }
                sb.append(" end.complemento like ? ");
            } // fim do campo complemento
 
            // Campo bairro
            if (endereco.getBairro() != null) {
                if (!whereAdd) {
                    sb.append(" WHERE ");
                    whereAdd = true;
                } else {
                    sb.append(" AND ");
                }
                sb.append(" end.bairro like ? ");
            } // fim do campo bairro
 
            // Campo cidade
            if (endereco.getCidade() != null) {
                if (!whereAdd) {
                    sb.append(" WHERE ");
                    whereAdd = true;
                } else {
                    sb.append(" AND ");
                }
                sb.append(" end.cidade like ? ");
            } // fim do campo cidade
 
            // Campo estado
            if (endereco.getEstado() != null) {
                if (!whereAdd) {
                    sb.append(" WHERE ");
                    whereAdd = true;
                } else {
                    sb.append(" AND ");
                }
                sb.append(" end.estado like ? ");
            } // fim do campo estado
 
            // Campo pais
            if (endereco.getPais() != null) {
                if (!whereAdd) {
                    sb.append(" WHERE ");
                    whereAdd = true;
                } else {
                    sb.append(" AND ");
                }
                sb.append(" end.pais like ? ");
            } // fim do campo pais
 
            // obtem a instancia da classe Connection
            c = Conexao.getConnection();
            ps = c.prepareStatement(sb.toString());
            int pos = 0;
 
            // Campo rua
            if (endereco.getRua() != null) {
                ps.setObject(pos++, "%" + endereco.getRua() + "%");
            } // fim do campo rua
 
            // Campo numero
            if (endereco.getNumero() != null) {
                ps.setObject(pos++, endereco.getNumero());
            } // fim do campo numero
 
            // Campo complemento
            if (endereco.getComplemento() != null) {
                ps.setObject(pos++, "%" + endereco.getComplemento() + "%");
            } // fim do campo complemento
 
            // Campo bairro
            if (endereco.getBairro() != null) {
                ps.setObject(pos++, "%" + endereco.getBairro() + "%");
            } // fim do campo bairro
 
            // Campo cidade
            if (endereco.getCidade() != null) {
                ps.setObject(pos++, "%" + endereco.getCidade() + "%");
            } // fim do campo cidade
 
            // Campo estado
            if (endereco.getEstado() != null) {
                ps.setObject(pos++, "%" + endereco.getEstado() + "%");
            } // fim do campo estado
 
            // Campo pais
            if (endereco.getPais() != null) {
                ps.setObject(pos++, "%" + endereco.getPais() + "%");
            } // fim do campo pais
 
            rs = ps.executeQuery();
            List<Endereco> enderecos = new ArrayList<Endereco>();
            while (rs.next()) {
                Endereco endereco = new Endereco();
                endereco.setBairro(rs.getString("BAIRRO"));
                endereco.setCidade(rs.getString("CIDADE"));
                endereco.setComplemento(rs.getString("COMPLEMENTO"));
                endereco.setEstado(rs.getString("ESTADO"));
                endereco.setId(rs.getLong("ID"));
                endereco.setNumero(rs.getInt("NUMERO"));
                endereco.setPais(rs.getString("PAIS"));
                endereco.setRua(rs.getString("RUA"));
                enderecos.add(endereco);
            }
            return enderecos;
        } catch (SQLException e) {
            e.printStackTrace();
            throw e;
        } finally {
            // Fecha a conexao de todos os recursos do JDBC
            Conexao.close(rs, ps, c);
        }
    }

Repare que as linhas marcadas foram alteradas, mas apenas porque agora nós estamos buscando as informações a partir da instância de endereco e não mais de cada parâmetro individualmente.

Mas e se o filtro de busca conter outros campos que não estão presentes na classe model?

Por exemplo, se o cliente pedir para que dentro do filtro fosse adicionado o campo de nome do cliente. Não seria possível adicionar esse nome do cliente na classe model Endereco, pois seria um campo apenas para esse filtro de busca desta tela de pesquisa. Assim é necessário, ao adotar essa solução de utilizar uma classe model, verificar se não haverão problemas com relação a inserção de novos campos de busca nesse filtro.

Utilização de classes Data Transfer Object

Antes de continuar a leitura…

Nesse artigo utilizamos o pattern DTO. Se você não sabe o que significa DTO, por favor leia o artigo.

Uma outra forma de utilizar é criar uma classe de Data Transfer Object ou DTO. A classe EnderecoDTO seria um bom substituto para o problema relacionado no tópico anterior, o qual poderíamos no futuro adicionar novos campos de acordo com a necessidade sem impactar em outros aspectos do projeto, evitando assim problemas de adicionar campos em classes que representam a abstração negocial do projeto. O código abaixo mostra a alteração ao inserir a classe DTO, repare que o código permaneceu idêntico ao código anterior, somente mudando o tipo da classe no parâmetro do método.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
//Imports necessarios.....
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
 
//..... definicao da classe e outras coisas
 
    public List<Endereco> findByFilter(EnderecoDTO endereco){
        Connection c = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            boolean whereAdd = false;
 
            // definicao do SQL inicial
            StringBuilder sb = new StringBuilder("SELECT * FROM TB_ENDERECO as end ");
 
            // Campo rua
            if (endereco.getRua() != null) {
                if (!whereAdd) {
                    sb.append(" WHERE ");
                    whereAdd = true;
                }
                sb.append(" end.rua like ? ");
            } // fim do campo rua
 
            // Campo numero
            if (endereco.getNumero() != null) {
                if (!whereAdd) {
                    sb.append(" WHERE ");
                    whereAdd = true;
                } else {
                    sb.append(" AND ");
                }
                sb.append(" end.numero = ? ");
            } // fim do campo numero
 
            // Campo complemento
            if (endereco.getComplemento() != null) {
                if (!whereAdd) {
                    sb.append(" WHERE ");
                    whereAdd = true;
                } else {
                    sb.append(" AND ");
                }
                sb.append(" end.complemento like ? ");
            } // fim do campo complemento
 
            // Campo bairro
            if (endereco.getBairro() != null) {
                if (!whereAdd) {
                    sb.append(" WHERE ");
                    whereAdd = true;
                } else {
                    sb.append(" AND ");
                }
                sb.append(" end.bairro like ? ");
            } // fim do campo bairro
 
            // Campo cidade
            if (endereco.getCidade() != null) {
                if (!whereAdd) {
                    sb.append(" WHERE ");
                    whereAdd = true;
                } else {
                    sb.append(" AND ");
                }
                sb.append(" end.cidade like ? ");
            } // fim do campo cidade
 
            // Campo estado
            if (endereco.getEstado() != null) {
                if (!whereAdd) {
                    sb.append(" WHERE ");
                    whereAdd = true;
                } else {
                    sb.append(" AND ");
                }
                sb.append(" end.estado like ? ");
            } // fim do campo estado
 
            // Campo pais
            if (endereco.getPais() != null) {
                if (!whereAdd) {
                    sb.append(" WHERE ");
                    whereAdd = true;
                } else {
                    sb.append(" AND ");
                }
                sb.append(" end.pais like ? ");
            } // fim do campo pais
 
            // obtem a instancia da classe Connection
            c = Conexao.getConnection();
            ps = c.prepareStatement(sb.toString());
            int pos = 0;
 
            // Campo rua
            if (endereco.getRua() != null) {
                ps.setObject(pos++, "%" + endereco.getRua() + "%");
            } // fim do campo rua
 
            // Campo numero
            if (endereco.getNumero() != null) {
                ps.setObject(pos++, endereco.getNumero());
            } // fim do campo numero
 
            // Campo complemento
            if (endereco.getComplemento() != null) {
                ps.setObject(pos++, "%" + endereco.getComplemento() + "%");
            } // fim do campo complemento
 
            // Campo bairro
            if (endereco.getBairro() != null) {
                ps.setObject(pos++, "%" + endereco.getBairro() + "%");
            } // fim do campo bairro
 
            // Campo cidade
            if (endereco.getCidade() != null) {
                ps.setObject(pos++, "%" + endereco.getCidade() + "%");
            } // fim do campo cidade
 
            // Campo estado
            if (endereco.getEstado() != null) {
                ps.setObject(pos++, "%" + endereco.getEstado() + "%");
            } // fim do campo estado
 
            // Campo pais
            if (endereco.getPais() != null) {
                ps.setObject(pos++, "%" + endereco.getPais() + "%");
            } // fim do campo pais
 
            rs = ps.executeQuery();
            List<Endereco> enderecos = new ArrayList<Endereco>();
            while (rs.next()) {
                Endereco endereco = new Endereco();
                endereco.setBairro(rs.getString("BAIRRO"));
                endereco.setCidade(rs.getString("CIDADE"));
                endereco.setComplemento(rs.getString("COMPLEMENTO"));
                endereco.setEstado(rs.getString("ESTADO"));
                endereco.setId(rs.getLong("ID"));
                endereco.setNumero(rs.getInt("NUMERO"));
                endereco.setPais(rs.getString("PAIS"));
                endereco.setRua(rs.getString("RUA"));
                enderecos.add(endereco);
            }
            return enderecos;
        } catch (SQLException e) {
            e.printStackTrace();
            throw e;
        } finally {
            // Fecha a conexao de todos os recursos do JDBC
            Conexao.close(rs, ps, c);
        }
    }

 

Removendo o condicional para o WHERE e AND

Agora vamos começar a melhorar a forma de adicionar as informações referentes ao filtro. É necessário construir a remoção dos IFs relacionados as clausulas WHERE e AND. Vamos estabelecer um padrão de trabalho, assim o primeiro item a ser realizado é ter a certeza de que ao menos um atributo da classe DTO está preenchido. Então vamos colocar um if verificando se os atributos não estão preenchidos.

Uma observação aqui, já que poderíamos ter um método em outra camada, Business Control por exemplo ou no próprio DTO, que realizaria a validação se um dos itens estão preenchidos. Como não estamos trabalhando com várias camadas nesse artigo, mas apenas apresentando um método de exemplo, dessa forma, se faz necessário inserirmos esse IF aqui.

A partir desse IF é possível inserir o WHERE no SQL inicial, removendo assim os ifs relacionados a parte do WHERE.

Para remover os IFs da parte relacionada aos ANDs vamos adicionar uma condição com o SQL inicial (1=1). Isso servirá para que seja acrescentado um AND no começo da nova condição.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//Imports necessarios.....
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
 
//..... definicao da classe e outras coisas
 
    public List<Endereco> findByFilter(EnderecoDTO endereco) {
        if (endereco.getRua() == null && endereco.getNumero() == null &&
            endereco.getComplemento() == null && endereco.getBairro() == null &&
            endereco.getCidade() == null && endereco.getEstado() == null && endereco.getPais() == null) {
            throw new Exception("Favor preencher ao menos um campo do filtro de pesquisa!");
        }
 
        // definicao do SQL inicial
        StringBuilder sb = new StringBuilder("SELECT * FROM TB_ENDERECO as end WHERE 1=1 ");
 
        Connection c = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
 
        try {
            // Campo rua
            if (endereco.getRua() != null) {
                sb.append(" AND end.rua like ? ");
            } // fim do campo rua
 
            // Campo numero
            if (endereco.getNumero() != null) {
                sb.append(" AND end.numero = ? ");
            } // fim do campo numero
 
            // Campo complemento
            if (endereco.getComplemento() != null) {
                sb.append(" AND end.complemento like ? ");
            } // fim do campo complemento
 
            // Campo bairro
            if (endereco.getBairro() != null) {
                sb.append(" AND end.bairro like ? ");
            } // fim do campo bairro
 
            // Campo cidade
            if (endereco.getCidade() != null) {
                sb.append(" AND end.cidade like ? ");
            } // fim do campo cidade
 
            // Campo estado
            if (endereco.getEstado() != null) {
                sb.append(" AND end.estado like ? ");
            } // fim do campo estado
 
            // Campo pais
            if (endereco.getPais() != null) {
                sb.append(" AND end.pais like ? ");
            } // fim do campo pais
 
            // obtem a instancia da classe Connection
            c = Conexao.getConnection();
            ps = c.prepareStatement(sb.toString());
            int pos = 0;
 
            // Campo rua
            if (endereco.getRua() != null) {
                ps.setObject(pos++, "%" + endereco.getRua() + "%");
            } // fim do campo rua
 
            // Campo numero
            if (endereco.getNumero() != null) {
                ps.setObject(pos++, endereco.getNumero());
            } // fim do campo numero
 
            // Campo complemento
            if (endereco.getComplemento() != null) {
                ps.setObject(pos++, "%" + endereco.getComplemento() + "%");
            } // fim do campo complemento
 
            // Campo bairro
            if (endereco.getBairro() != null) {
                ps.setObject(pos++, "%" + endereco.getBairro() + "%");
            } // fim do campo bairro
 
            // Campo cidade
            if (endereco.getCidade() != null) {
                ps.setObject(pos++, "%" + endereco.getCidade() + "%");
            } // fim do campo cidade
 
            // Campo estado
            if (endereco.getEstado() != null) {
                ps.setObject(pos++, "%" + endereco.getEstado() + "%");
            } // fim do campo estado
 
            // Campo pais
            if (endereco.getPais() != null) {
                ps.setObject(pos++, "%" + endereco.getPais() + "%");
            } // fim do campo pais
 
            rs = ps.executeQuery();
            List<Endereco> enderecos = new ArrayList<Endereco>();
            while (rs.next()) {
                Endereco e = new Endereco();
                e.setBairro(rs.getString("BAIRRO"));
                e.setCidade(rs.getString("CIDADE"));
                e.setComplemento(rs.getString("COMPLEMENTO"));
                e.setEstado(rs.getString("ESTADO"));
                e.setId(rs.getLong("ID"));
                e.setNumero(rs.getInt("NUMERO"));
                e.setPais(rs.getString("PAIS"));
                e.setRua(rs.getString("RUA"));
                enderecos.add(e);
            }
            return enderecos;
        } catch (SQLException e) {
            e.printStackTrace();
            throw new Exception("Problemas no sistema, por favor tente mais tarde");
        } finally {
            // Fecha a conexao de todos os recursos do JDBC
            Conexao.close(rs, ps, c);
        }
    }

 

Utilizando um Map para os parâmetros

Um Map, de acordo com a ciência da computação, é:

Na ciência da computação, existem duas definições da palavra Map. A primeira é um array associativo, um tipo de container que mapeia valores de um tipo para valores de outro tipo. Um exemplo disso é o STL map((API interface MAP – http://docs.oracle.com/javase/7/docs/api/java/util/Map.html)). A segunda definição vêm da programação funcional, na qual cada map é uma função que obtém uma lista e uma função, a qual é aplicada sobre todos os elementos da lista e, ao final, retorna uma lista de resultados.

Assim o Map pode ser utilizado para armazenar valores a partir de uma determinada chave. Dessa forma, vamos adaptar as passagens de parâmetros para o JDBC em nosso método de busca.

O primeiro trabalho a ser realizado é criar uma nova instância de java.util.Map. Como você talvez saiba, Map na verdade é uma interface, dessa forma devemos dar um new em uma de suas filhas para realizar a instanciação. Nesse exemplo iremos utilizar o java.util.HashMap, conforme a linha 30 do código abaixo ao criar a variável parameters.

Outro aspecto a ser feito é trazer a declaração da variável pos para o início do método e mudar o tipo para o wrapper, Integer, conforme linha 31, para não existir problemas na hora de informar a posição atual.

Por último e mais importante, iremos reduzir a duplicidade dos IFs, pois iremos trazer a atribuição de cada valor para dentro do Map e mais adiante no código iremos trabalhar a parte de atribuições no PreparedStatement, conforme mostram as linhas destacadas dentro de cada IF.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//Imports necessarios.....
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
 
//..... definicao da classe e outras coisas
 
    public List<Endereco> findByFilter(EnderecoDTO endereco) {
        if (endereco.getRua() == null && endereco.getNumero() == null &&
            endereco.getComplemento() == null && endereco.getBairro() == null &&
            endereco.getCidade() == null && endereco.getEstado() == null && endereco.getPais() == null) {
            throw new Exception("Favor preencher ao menos um campo do filtro de pesquisa!");
        }
 
        // definicao do SQL inicial
        StringBuilder sb = new StringBuilder("SELECT * FROM TB_ENDERECO as end WHERE 1=1 ");
 
        Connection c = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
 
        try {
            Map<Integer, Object> parameters = new HashMap<>();
            Integer pos = 0;
 
            // Campo rua
            if (endereco.getRua() != null) {
                sb.append(" AND end.rua like ? ");
                parameters.put(pos++, "%" + endereco.getRua() + "%");
            } // fim do campo rua
 
            // Campo numero
            if (endereco.getNumero() != null) {
                sb.append(" AND end.numero = ? ");
                parameters.put(pos++, endereco.getNumero());
            } // fim do campo numero
 
            // Campo complemento
            if (endereco.getComplemento() != null) {
                sb.append(" AND end.complemento like ? ");
                parameters.put(pos++, "%" + endereco.getComplemento() + "%");
            } // fim do campo complemento
 
            // Campo bairro
            if (endereco.getBairro() != null) {
                sb.append(" AND end.bairro like ? ");
                parameters.put(pos++, "%" + endereco.getBairro() + "%");
            } // fim do campo bairro
 
            // Campo cidade
            if (endereco.getCidade() != null) {
                sb.append(" AND end.cidade like ? ");
                parameters.put(pos++, "%" + endereco.getCidade() + "%");
            } // fim do campo cidade
 
            // Campo estado
            if (endereco.getEstado() != null) {
                sb.append(" AND end.estado like ? ");
                parameters.put(pos++, "%" + endereco.getEstado() + "%");
            } // fim do campo estado
 
            // Campo pais
            if (endereco.getPais() != null) {
                sb.append(" AND end.pais like ? ");
                parameters.put(pos++, "%" + endereco.getPais() + "%");
            } // fim do campo pais
 
            // obtem a instancia da classe Connection
            c = Conexao.getConnection();
            ps = c.prepareStatement(sb.toString());
 
            for (Entry<Integer, Object> entry : parameters.entrySet()) {
                ps.setObject(entry.getKey(), entry.getValue());
            }
 
            rs = ps.executeQuery();
            List<Endereco> enderecos = new ArrayList<Endereco>();
            while (rs.next()) {
                Endereco e = new Endereco();
                e.setBairro(rs.getString("BAIRRO"));
                e.setCidade(rs.getString("CIDADE"));
                e.setComplemento(rs.getString("COMPLEMENTO"));
                e.setEstado(rs.getString("ESTADO"));
                e.setId(rs.getLong("ID"));
                e.setNumero(rs.getInt("NUMERO"));
                e.setPais(rs.getString("PAIS"));
                e.setRua(rs.getString("RUA"));
                enderecos.add(e);
            }
            return enderecos;
        } catch (SQLException e) {
            e.printStackTrace();
            throw new Exception("Problemas no sistema, por favor tente mais tarde");
        } finally {
            // Fecha a conexao de todos os recursos do JDBC
            Conexao.close(rs, ps, c);
        }
    }

finnaly{

Essa foi o artigo relacionado a organização de um código Java, utilizando SQL e JDBC para um método de busca com filtros. Existem outras coisas que você poderia fazer como a parte de obter as informações de um Result Set estar em um método separado, ou até mesmo os IFs estarem em outro método. Mas o ponto aqui é a utilização de coisas simples, como convenção de parâmetros, utilização de métodos da classe String e de estruturas de dados correspondentes para melhorar a escrita de um método que muitas vezes não temos muito o que melhorar.

Duvidas ou sugestões? Deixe seu feedback! Isso ajuda a saber a sua opinião sobre os artigos e melhorá-los para o futuro! Isso é muito importante!

Até um próximo post!

Filed Under: Java, JDBC Tagged With: dto, Java, JDBC, SQL

About Mauda

Mestre em Informática, Analista de Sistemas, Professor, SCJP e Baterista. Desde 2002 trabalhando no mundo Java e ensinando pessoas sobre desenvolvimento de sistemas. Mais informações

Reader Interactions

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Advertisements

Copyright © 2025 · Genesis Framework · WordPress · Log in