java - 使用 ResultSetTableModel 删除 JTable 选中的行

标签 java database swing jdbc

我使用 ResultSetTableModel 类将我的数据库数据显示到 JTable 中。

public class ResultSetTableModel extends AbstractTableModel {

private Connection connection;
private Statement statement;
private PreparedStatement prstatement;
private ResultSet resultSet;
private ResultSetMetaData metaData;
private int numberOfRows;
private boolean connectedToDatabase = false;

public ResultSetTableModel(String driver, String url,
        String username, String password, String query)
        throws SQLException, ClassNotFoundException {

    Class.forName(driver);

    connection = DriverManager.getConnection(url, username, password);

    prstatement = (PreparedStatement) connection.createStatement(
            ResultSet.TYPE_SCROLL_INSENSITIVE,
            ResultSet.CONCUR_READ_ONLY);

    connectedToDatabase = true;
    setQuery(query);
}

@Override
public Class getColumnClass(int column) throws IllegalStateException {
    if (!connectedToDatabase) {
        throw new IllegalStateException("Not Connected to Database");
    }

    try {
        String className = metaData.getColumnClassName(column + 1);

        return Class.forName(className);
    } catch (Exception exception) {
        exception.printStackTrace();
    }

    return Object.class;
}

@Override
public int getColumnCount() throws IllegalStateException {
    if (!connectedToDatabase) {
        throw new IllegalStateException("Not Connected to Database");
    }
    try {
        return metaData.getColumnCount();

    } catch (SQLException sqlException) {
        sqlException.printStackTrace();
    }
    return 0;
}

@Override
public String getColumnName(int column) throws IllegalStateException {
    if (!connectedToDatabase) {
        throw new IllegalStateException("Not Connected to Database");
    }
    try {
        return metaData.getColumnName(column + 1);
    } catch (SQLException sqlException) {
        sqlException.printStackTrace();
    }
    return "";
}

@Override
public int getRowCount() throws IllegalStateException {
    if (!connectedToDatabase) {
        throw new IllegalStateException("Not Connected to Database");
    }
    return numberOfRows;
}

@Override
public Object getValueAt(int row, int column)
        throws IllegalStateException {
    if (!connectedToDatabase) {
        throw new IllegalStateException("Not Connected to Database");
    }
    try {
        resultSet.absolute(row + 1);
        return resultSet.getObject(column + 1);
    } catch (SQLException sqlException) {
        sqlException.printStackTrace();
    }

    return "";
}

public void setQuery(String query)
        throws SQLException, IllegalStateException {
    if (!connectedToDatabase) {
        throw new IllegalStateException("Not Connected to Database");
    }
    int a = prstatement.executeUpdate(query);  
    metaData = resultSet.getMetaData();

    resultSet.last();                   // move to last row
    numberOfRows = resultSet.getRow();  // get row number      

    fireTableStructureChanged();
}

public void disconnectFromDatabase() {
    if (!connectedToDatabase) {
        return;
    }

    try {
        prstatement.close();
        connection.close();
    } catch (SQLException sqlException) {
        sqlException.printStackTrace();
    } finally
    {
        connectedToDatabase = false;
    }
}

public void removeRecord(int row) throws SQLException {
    String deleteQuery = "delete from mytable where id=?";
    PreparedStatement pStatement = connection.prepareStatement(deleteQuery);
    pStatement.setInt(1, row);
    int rowsAffected = pStatement.executeUpdate();
}
}

我的第二堂课:

public class d7Table extends JFrame implements ActionListener {

String dbUrl = "jdbc:mysql://localhost/mydb";
String dbDriver = "com.mysql.jdbc.Driver";
public JTable table;
public JButton dellButton;
ResultSetTableModel rstm;
public int selectedRow;

public d7Table() {
    try {
        rstm = new ResultSetTableModel(dbDriver, dbUrl,
                "root", "2323", "select * from mytable");
        table = new JTable(rstm);

    } catch (SQLException ex) {
        System.out.println("Could not connect to database");
    } catch (ClassNotFoundException cnfe) {
    }

    add(new JScrollPane(table), BorderLayout.CENTER);
    add(buttonsPanel(), BorderLayout.SOUTH);

    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setSize(800, 600);
    this.setLocation(300, 60);
    this.setVisible(true);
}

public JPanel buttonsPanel() {
    JPanel buttonP = new JPanel();
    dellButton = new JButton("Delete");
    dellButton.addActionListener(this);
    buttonP.add(dellButton);
    return buttonP;
}

@Override
public void actionPerformed(ActionEvent e) {
     if(e.getSource()== dellButton){
        selectedRow = table.getSelectedRow();
        if(selectedRow>0){
            try{
                rstm.removeRecord(selectedRow);
            }
            catch(SQLException sqle){
                sqle.printStackTrace();
            }
        }
        else{
            System.out.println("Select a row");
        }
    }
}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            new d7Table();
        }
    });
}
}

Now, my table populate correctly, But when select a row and clicked to delete, nothing happens!

最佳答案

错误很明显 - executeQuery 不能用于数据库写入操作。

使用executeUpdate反而。

使用PreparedStatement 而不是Statement 来防止SQL Injection攻击。然后通过将其所有逻辑封装在方法中而不是与 setQuery 共享来简化 removeRecord

public void removeRecord(int row) throws SQLException {
    String deleteQuery = "delete from mytable where id=?";
    PreparedStatement statement = connection.prepareStatement(deleteQuery);
    statement.setInt(1, row);
    int rowsAffected = statement.executeUpdate();
}

另外:setQuery 不是一个简单的 setter,重命名为 updateFromDatabase

关于java - 使用 ResultSetTableModel 删除 JTable 选中的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17846079/

相关文章:

php - 复制后编码混淆

php - 无法为 mysql 声明变量 (whmcs)

java - JSplitPane : Possible to have one side empty/transparent to see lower layer underneath?

java - 删除 JButton 的边框

mysql - 如何在 MARIADB/MYSQL 中为函数/过程声明表到变量?

java - 在java中获取具有焦点的组件

java - 使用 Guava Multimap 表示 xml 名称和值

java - 从另一个线程访问对象

java - 编写一个程序,将用户的输入作为数组进行比较,并使用 while 循环将其与另一个数组进行比较以检查正确答案

java - 为 HBox 设置背景图像 - JavaFX