Estou fazendo uma tela dentro do VSCode para mostrar uma tabela e dentro dela há valores do meu banco de dados. A opção de remover um dado da tabela não funciona.
Verifiquei as condições, estão certas; verifiquei o código em SQL e também tá certo. Acho que o erro pode estar na PreparedStatement.
Será que o auto-commit não está desabilitado e faltou vc invocar o commit()
depois do execute()
?
o auto-commit tá definido como true, não deu certo
E não aparece erro nenhum no terminal?
Pode nos mostrar a classe ConnectionFactory
?
Não aparece erro no terminal.
O comando de Insert funciona normalmente, então acho que o problema não está na conexão.
O registro não é excluído do banco de dados ou ele não é removido do seu table model?
Olhando o código, parece estar correto, porém, aparentemente você não remove a linha do registro excluído do seu table model, não seria esse o caso?
1 curtida
Ele não é excluído do bd e nem removido do table model. O teste que eu fiz usando id = 3 em vez do id = ?, excluiu do bd e removeu do table model o dado com id 3. Porém usando o “?” não acontece nenhum dos dois.
Ah, então vai naquela linha na qual vc chama o c.getId()
e coloca um println
para ver se esse getId()
está retornando o id certo.
caramba, tá retornando 0. O atributo id tá como auto_increment no bd, então nem to colocando valor pra ele no construtor. Acho que ele não tá recebendo o valor do bd, como posso resolver isso?
Eu tenho uma ideia, mas deixa eu ver sua classe Categoria
e o método de inserção antes?
Claro, segue o código:
public class Categoria {
private int id;
private String nome;
public Categoria(String nome) {
this.nome = nome;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
}
Método de inserção:
public void insert(Categoria c) {
String sql = “insert into tbCategoria (Nome) values (?)”;
try {
Connection con = new ConnectionFactory().getConnection();
PreparedStatement st = con.prepareStatement(sql);
st.setString(1, c.getNome());
st.execute();
st.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
Beleza, então vc vai ter que fazer algumas modificações no método insert
.
Primeiro vc precisa trocar isto:
PreparedStatement st = con.prepareStatement(sql);
Por isto:
PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
Segundo: Logo após a linha st.execute();
, adicione este trecho:
try (ResultSet result = stmt.getGeneratedKeys()) {
if (result.next()) {
c.setId(result.getInt(1));
}
}
Abaixo está o código completo que usei para fazer os testes aqui. No caso eu usei o H2 para facilitar, mas no MySQL é a mesma coisa.
No meu código usei o try-with-resources, pois ele garante o fechamento dos recursos sem que precisemos invocar o close()
explicitamente.
Código que usei para testar
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Main {
private static final String sql = "INSERT INTO tbCategoria (Nome) VALUES (?)";
private static void insert(Categoria c) {
try (
Connection conn = DriverManager.getConnection("jdbc:h2:mem:db;INIT=RUNSCRIPT FROM 'classpath:db.sql';MODE=MYSQL");
PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)
) {
stmt.setString(1, c.getNome());
if (stmt.executeUpdate() > 0) {
try (ResultSet result = stmt.getGeneratedKeys()) {
if (result.next()) {
c.setId(result.getInt(1));
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void main(String... args) {
Categoria c = new Categoria("Eletrônicos");
insert(c);
System.out.println(c);
}
}
class Categoria {
private int id;
private String nome;
Categoria(String nome) {
this.nome = nome;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String name) {
this.nome = name;
}
@Override
public String toString() {
return "{id=%d, name=%s}".formatted(this.id, this.nome);
}
}
Deu erro no RETURN_GENERATED_KEYS:
“RETURN_GENERATED_KEYS cannot be resolved or is not a field”
Vê se vc importou o Statement
correto. O certo é:
import java.sql.Statement;
É importante checar porque tem uma classe com este mesmo nome, mas o pacote é diferente, é o java.beans.Statement
. O correto é java.sql.Statement
.
É, tinha importado um pacote diferente. Troquei o import mas mesmo assim não funcionou, o getId() continua retornando 0.
Me mostra como tá o método insert agora.
public void insert(Categoria c) {
String sql = “insert into tbCategoria (Nome) values (?)”;
try (
Connection con = new ConnectionFactory().getConnection();
PreparedStatement st = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);) {
st.setString(1, c.getNome());
st.execute();
try (ResultSet result = st.getGeneratedKeys()) {
if (result.next()) {
c.setId(result.getInt(1));
}
}
st.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
Coloca um print
ou um breakpoint pra ver se ele tá caindo do if (result.next())
.
E me mostra a parte que chama o método insert
.
Ele não tá entrando no if.
O código que puxa o insert é de um botão na tela:
public void btCadastrarClick(ActionEvent e) {
String nome = JOptionPane.showInputDialog(this, “Insira o nome”, null);
Categoria c = new Categoria(nome);
CategoriaDAO cd = new CategoriaDAO();
cd.insert(c);
this.setVisible(false);
this.setVisible(true);
}
Em teoria, se vc colocasse um print logo abaixo de cd.insert(c)
, vc veria o id atualizado.
Mas se nem tá entrando naquele if, então deve ser outro problema.
Vc pode mostrar o seu CREATE TABLE?
1 curtida