Bom dia a todos do forum. Tenho uma dúvida com relação ao retorno do método next() da interface ResultSet, estou fazendo um teste de cadastro de cliente e para efeito de negócio, como se trata de um teste, decidi que não podem haver dois clientes com o mesmo nome, então criei os métodos abaixo:
public static boolean isJaGravadoNoBD(ClienteDTO clienteDTO) throws SQLException, PersistenciaException{
String query = "SELECT * FROM petshop.cliente WHERE nome = " + "'" + clienteDTO.getNome() + "'";
ResultSet rs = ConexaoUtil.consultar(query);
//System.out.println(rs.wasNull());
try {
if(rs != null && rs.next()){
return true;//rs.first();//Desta maneira não funcionou
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public static ResultSet consultar(String query){
try {
Connection con = ConexaoUtil.getInstance().getConnection();
PreparedStatement pstm = con.prepareStatement(query);
ResultSet rs = pstm.executeQuery();
if(rs.next()){
return rs;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
A Primeira versão do método isJaGravadoNoBD não funcionou, pois permitia que eu gravasse os dados mesmo que já houvesse um cliente com o mesmo nome,então dei uma olhada na documentação e fiz a segunda versão, esta funcionou, mas confesso que não entendi:
public static boolean isJaGravadoNoBD(ClienteDTO clienteDTO) throws SQLException, PersistenciaException{
String query = "SELECT * FROM petshop.cliente WHERE nome = " + "'" + clienteDTO.getNome() + "'";
ResultSet rs = ConexaoUtil.consultar(query);
//System.out.println(rs.wasNull());
try {
if(rs != null && !rs.next()){
return rs.first();
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
Minha dúvida é: Por que a primeira versão não funcionou, tem algo a ver com a posição do cursor na hora da primeira consulta? Porque debugando, mesmo com a query preenchida, ele estava retornando false. Se puderem me ajudar com essa dúvida eu agradeço. Abraço a todos.
Fala ae,
Bom Não consegui entender o porque do teste, mas por precaução tenta fechar a conexão depois que ele realizar o procedimento.
public static ResultSet consultar(String query){
try {
Connection con = ConexaoUtil.getInstance().getConnection();
PreparedStatement pstm = con.prepareStatement(query);
ResultSet rs = pstm.executeQuery();
if(rs.next()){
return rs;
}
con.close();
pstm.close();
rs.close();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Hadamanthys, valeu pela resposta.
Quanto a fechar a conexão, é um detalhe importante que esqueci, mas não sei se isso responde minha dúvida, vou testar.
Acho que achei seu erro.
O método next() da classe ResultSet, faz o ResultSet “apontar” pro próximo elemento da lista. Quando você cria o ResultSet, ele inicialmente está na posição ZERO, ou seja, antes do primeiro elemento do resultado.
No seu método consultar:
public static ResultSet consultar(String query){
try {
Connection con = ConexaoUtil.getInstance().getConnection();
PreparedStatement pstm = con.prepareStatement(query);
ResultSet rs = pstm.executeQuery();
if(rs.next()){
return rs;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Você dá um if(rs.next()), ou seja, executa o método uma vez e aponta pra primeira posição. Logo em seguida, no método isJaGravadoNoBD, você checa se rs.next() novamente, e caso só haja 1 elemento, que é o seu caso, ele vai tentar apontar para o segundo elemento da lista, que não existe, retornando false, quando deveria retornar true.
Para consertar isso apenas mude seu método consultar para:
public static ResultSet consultar(String query){
try {
Connection con = ConexaoUtil.getInstance().getConnection();
PreparedStatement pstm = con.prepareStatement(query);
ResultSet rs = pstm.executeQuery();
if(rs != null){
return rs;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Assim sua verificação funcionará, apesar de ainda ser redundante usar o método next() na verificação.
Espero ter ajudado.
JoaoOliveiraMlp,
Obrigado pela sua resposta, e mais que isso, pela explicação ao invés de apenas postar o código que resolve, eu testei a sua sugestão e funcionou perfeitamente, mas o melhor foi entender o que eu estou fazendo, poderia apenas me explicar o que você quis dizer quando falou que é redundante o uso do método next()? Abraço.
Nessa sua validação aqui:
if(rs != null && rs.next()){
return true;//rs.first();//Desta maneira não funcionou
}
Só validar se rs é nulo já é o suficiente pra saber se a busca retornou algo, não precisa usar o next() não, tudo que o next faz é apontar pro próximo elemento.
JoaoOliveiraMlp,
Obrigado mais uma vez, ajudou muito. Abraço.