Dúvida em estrutura de um metodo de alterar senha

19 respostas
LostSpirit

Bom eu fiz um metodo para alterar senha

onde ele faz um select no banco de dados para ver se o login e a senha digitada são iguais no banco de dados

String sql = "SELECT id_usuario,nome,senha FROM usuario where login = ? and senha = ?";
        try {
            PreparedStatement stmt = con.prepareStatement(sql);
            stmt.setString(1, u.getLogin());
            stmt.setString(2, u.getSenha());
            ResultSet rs = stmt.executeQuery();

e depois eu fiz essa verificação com um if:

if (rs.next()){

String update = "UPDATE usuario SET senha=? WHERE id_usuario = " +Sessao.getInstancia().getUsuario().getId()+ “”;

PreparedStatement stmt2 = con.prepareStatement(sql);

stmt2.setString(1, u.getNovaSenha());

ResultSet rs2 = stmt2.executeQuery();

return true;

}

para fazer o update da senha se o id for igual o id do usuario conectado
eu debuguei e verifiquei que o está pegando o id do usuario normalmente, mas está dando esse error:

GRAVE: null
java.sql.SQLException: No value specified for parameter 2

eu sei que tem relação com a estrutura, mas eu não faço ideia onde eu errei
e como e onde eu fecharia a conexão com o bd dps disso?

19 Respostas

adriano_si

stmt2 está com o seu SQL original e não com o update… :wink:

LostSpirit

opa mano me falaram que desse modo que eu fiz eu posso tomar sql injection pq eu abri novamente a conexão?

marcospaulo.suporte

Só mudar

PreparedStatement stmt2 = con.prepareStatement(sql);

para:

PreparedStatement stmt2 = con.prepareStatement(update);
LostSpirit

então mano, mas nesse codigo ficar vulnerávela sql injection?
você poderia me dar uma dica de como fazer um codigo mais clean ?

marcospaulo.suporte

Não fica vulnerável não. Só pra vc tentar entender melhor o tema:

A maioria dos bancos de dados relacionais lida com uma consulta ( query ) JDBC / SQL em quatro passos:

  1. Interpretar ( parse ) a consulta SQL;
  2. Compilar a consulta SQL;
  3. Planejar e otimizar o caminho de busca dos dados;
  4. Executar a consulta otimizada, buscando e retornando os dados.

Um Statement irá sempre passar pelos quatro passos acima para cada consulta SQL enviada para o banco.

Já um Prepared Statement pré-executa os passos (1) a (3). Então, ao criar um Prepared Statement alguma pré-otimização é feita de imediato. O efeito disso é que, se você pretende executar a mesma consulta repetidas vezes mudando apenas os parâmetros de cada uma, a execução usando Prepared Statements será mais rápida e com menos carga sobre o banco.

Outra vantagem dos Prepared Statements é que, se utilizados corretamente, ajudam a evitar ataques de Injeção de SQL. Note que para isso é preciso que os parâmetros da consulta sejam atribuídos através dos métodos setInt() , setString() , etc. presentes na interface PreparedStatement e não por concatenação de strings.

Para uma consulta que vai ser executada poucas vezes e não requer nenhum parâmetro, Statement basta. Para os demais casos, prefira PreparedStatement.

Fonte: Wikipedia

marcospaulo.suporte

Pra fechar o banco depois, vc deve ter um método close() no seu ConnectionFactory.

aí é só dar um

con.close();

Ou algo do tipo, depende como chama o seu método.

LostSpirit

opa vlw mano

eu dei uma melhora no codigo (creio eu )
mas estou com um erro e uma dúvida:
o meu error:

GRAVE: null
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column ‘adm’ in ‘where clause’

e quando eu vou debugar a string sql fica assim:
UPDATE usuario SET senha=? WHERE id_usuario = 2 and login=adm and senha=?

ou seja não está pegando a

stmt.setString(1, u.getNovaSenha());

stmt.setString(2, u.getSenha());

quando eu faço o login eu salvo todos os dados login id nome senha etc ( vc me deu a dica de fazer um singleton eu fiz), e quando eu vou passar os dados para esse metodo:

public void alterarSenha2(){
String login = txtLogin.getText(), senha=txtSenha.getText(), novaSenha = txtConfirm.getText();
Usuario usuario = new Usuario(login,senha,novaSenha);
aFachada.getInstancia().validarSenhaUsuario(usuario);
}

você poderia me ajudar ?

LostSpirit

creio eu que estou com uma logica errada pois vou está escrevendo uma nova senha ao setar a senha
estou meio confuso hehe .

adriano_si

Aprenda a ler o seus erros: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column ‘adm’ in ‘where clause’

Volte ao seu select e veja que na cláusula where tem um login=adm. Não existe nenhuma palavra chave na sintaxe do mysql pra ele saber o que você quer fazer aí e se existe também não faz sentido no seu select. Logo pra funcionar, seu adm deve ser o login do usuário que você quer atualizar, então faça login = ‘adm’ com seu adm coberto por aspas simples. :wink:

marcospaulo.suporte

Ou seja, ele está dizendo que não existe a coluna ‘adm’ do seu where. Por ser string (varchar pro banco) o adm ou a variável deveria estar entre aspas simples.

de:

UPDATE usuario SET senha=? WHERE id_usuario = 2 and login=adm and senha=?

para:

UPDATE usuario SET senha=? WHERE id_usuario = 2 and login='adm' and senha=?

Arruma esse e posta o outro erro que vai dar.

LostSpirit

ah sim entendi, mas a logica que tive está errada não é?
eu teria que dar um select antes…
pq ao logar eu salvo a senha do usuario, e nesse metodo eu vou setar um novo usuario com uma senha ( ele pode colocar outra senha diferente da do login )

tou meio confuso como fzr esse metodo kk

LostSpirit

obrigado mano não tinha me atentando a isso de aspas .

marcospaulo.suporte

Em que momento vc está tentando alterar a senha do usuário?

Se o usuário logou e vc armazenou o ID dele, blza, vc já pode fazer o update.
Se o usuário não logou ainda, o ID vai ser ‘null’ e vai dar erro de NullException, nesse segundo caso vc tem que pedir os dados dele, verificar se existe e armazenar o ID pra depois fazer o update.

Imagino que o ID nunca vai ser igual, deve ser chave primária pra vc no banco de dados. Se sim, pode mudar de:

UPDATE usuario SET senha=? WHERE id_usuario = 2 and login='adm' and senha=?

para:

UPDATE usuario SET senha=? WHERE id_usuario = 2

Assim, vc melhora performance do banco de dados, nesse simples caso talvez não se perceptível, mas se entender o conceito, em situações mais complicadas vai te ajudar.

LostSpirit

quando o usuario loga
mas o que eu estou falando é na tela de mudar senha vão ter 3 text fields login senha e nova senha
ele pode nesse textfield colocar uma senha diferente do banco de dados e mesmo assim vai funcionar pois vou está setando por construtor
Usuario usuario = new Usuario(login,senha,novaSenha);

eu estava pensando em fazer um if mas não sei se daria certo
Sessao.getInstancia().getUsuario().getSenha() == textfield da senha antiga { ai ele executa o metodo }
mas eu não sei se tem como fazer isso ou como fazer isso.

e essa seria a forma correta de passar uma string?

login=’ “+Sessao.getInstancia().getUsuario().getLogin()+” ’

marcospaulo.suporte

Sim, vc pode fazer um IF e analisar.

SE > if(Sessao.getInstancia().getUsuario().getSenha().equals(SEUtextfield)){
    FAÇA
}

e essa seria a forma correta de passar uma string?
login=’ “+Sessao.getInstancia().getUsuario().getLogin()+” ’

Porém, tome cuidado com espaços, pois:

login=' +Sessao.getInstancia().getUsuario().getLogin()+ '

é diferente de:

login='“+Sessao.getInstancia().getUsuario().getLogin()+”'

Sim, pq o JDBC vai fazer o banco interpretar isso, e pro banco, ele pede que textos sejam enviados entre ‘aspas’. Logo, vc define isso na sua query.

LostSpirit
eu tentei     if(Sessao.getInstancia().getUsuario().getSenha().equals(txtSenha)){

Usuario usuario = new Usuario(login,senha,novaSenha);

aFachada.getInstancia().validarSenhaUsuario(usuario);

}

e não está entrando no if eu debuguei pra checar

marcospaulo.suporte

mas não seria txtSenha.getText(); ?

LostSpirit

kkk é o sono me desculpa, vlw pela atenção mano aprendi bastante coisa com a sua ajuda desde o primeiro tópico que criei.

poderia me tirar mais uma dúvida?

eu criei uma tablelist
e botei ela como editavel
clmLogin.setCellFactory(
TextFieldTableCell.forTableColumn()
);

eu só tou com dúvida de quando mudar salver isso no banco de dados vc poderia dar uma luz?

marcospaulo.suporte

Que bom que tenha aprendido man, estamos aqui pra ajudar e ser ajudados mesmo.

Não manjo mto de JavaFx, mas dá uma olhada em ’ setOnEditCommit '.

Ou aqui à partir de : ‘Editing Data in the Table’

Criado 17 de junho de 2019
Ultima resposta 18 de jun. de 2019
Respostas 19
Participantes 3