使用ResultSetTableModel删除JTable选定的行

时间:2013-07-24 22:43:30

标签: 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();
        }
    });
}
}

现在,我的表格填充正确,但是当选择一行并点击删除时,没有任何反应!

1 个答案:

答案 0 :(得分:4)

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

请改用executeUpdate

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

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不是简单的设定者,重命名为updateFromDatabase