Dúvida em estrutura de um metodo de alterar senha

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?

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

2 curtidas

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

Só mudar

PreparedStatement stmt2 = con.prepareStatement(sql);

para:

PreparedStatement stmt2 = con.prepareStatement(update);

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

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

2 curtidas

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.

1 curtida

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 ?

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

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:

1 curtida

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.

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

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

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.

1 curtida

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()+” ’

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.

1 curtida

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

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

1 curtida

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?

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’

1 curtida