【问题标题】:Use ResultSetTableModel to delete JTable selected row使用 ResultSetTableModel 删除 JTable 选中的行
【发布时间】:2013-07-24 15:23:31
【问题描述】:

我使用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!

【问题讨论】:

    标签: java database swing jdbc


    【解决方案1】:

    错误很明显 - 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

    【讨论】:

    • 也不从 jframe 扩展,也不在顶级类中实现 actionlistener,但我想我已经告诉他了
    • @nachokk 我从JFrame 扩展并在我的d7Table 类中实现actionlistener,你的意思是什么?
    • 他的意思是只创建一个JFrame 实例并使用它而不是对其进行子类化:)
    • @Reimeus 我加了resultSet = prstatement.executeUpdate(query); 但不行
    • @Sajjad 不要更改问题的代码。这使得任何答案都不合适。专注于让原始代码工作然后切换到使用PreparedStatement。任何关于该问题的问题都属于新问题
    猜你喜欢
    • 2023-03-04
    • 2013-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-28
    • 2013-06-27
    • 1970-01-01
    • 2012-05-04
    相关资源
    最近更新 更多