首页 > 解决方案 > Java中的Sqlite“数据库锁定”错误以及如何更新TableView

问题描述

我正在编写一个动态填充 JavaFX TableView 的程序。一切正常,我可以一遍又一遍地使用相同的方法来填充来自各种查询的信息的多个表。我看到对此有很多问题,但我只是找不到这种情况的答案。

我的代码基于这个问题的答案。

但是,只有当我稍后在代码中尝试将功能分配给按钮时,才会出现我的问题。我可以从链接中多次调用上述方法来填充多个表,并且我尝试在连接上显式调用 .close() 并在我的各种方法中将其作为局部变量重新打开,从而每次重新打开它方法被调用,并且还将连接实例化为类变量。我只是想不通为什么我会继续接受这个领域,尽管一切。一般来说,我对编码比较陌生,所以我确信我错过了一些关于连接如何工作的信息。

此外,如果有人对如何在对 .db 文件进行更改后更新 TableView 有任何提示,那也很好。

这是我使用上述答案中的代码的具体方法。我所做的唯一修改是我为它提供了输入查询的参数,以及我想在其上显示我正在显示的三个表的查询结果的关联表,这对于填充表非常有用:

下面有一个屏幕截图作为上下文。

public void buildData(String query, TableView table) {
    data = FXCollections.observableArrayList();
    try {
        //SQL FOR SELECTING ALL OF CUSTOMER
        String SQL = query;
        //ResultSet
        ResultSet rs = c.createStatement().executeQuery(SQL);

        for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) {
            //We are using non property style for making dynamic table
            final int j = i;
            TableColumn col = new TableColumn(rs.getMetaData().getColumnName(i + 1));
            col.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList, String>, ObservableValue<String>>() {
                public ObservableValue<String> call(TableColumn.CellDataFeatures<ObservableList, String> param) {
                    return new SimpleStringProperty(param.getValue().get(j).toString());
                }
            });
            col.setMinWidth(200);

            table.getColumns().addAll(col);
            System.out.println("Column [" + i + "] ");
        }


        while (rs.next()) {
            //Iterate Row
            ObservableList<String> row = FXCollections.observableArrayList();
            for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
                //Iterate Column
                row.add(rs.getString(i));
            }
            System.out.println("Row [1] added " + row);
            data.add(row);

        }

        //FINALLY ADDED TO TableView
        table.setItems(data);

    } catch (Exception e) {
        e.printStackTrace();
        System.out.println("Error on Building Data");
    }
}

然后在这里出现了数据库锁定错误的问题,在单击“添加”按钮时我使用的这种方法中,我认为使用相同的 Connection c 会有所作为,但事实并非如此。另外,就像我说的那样,我尝试在每次使用后关闭连接,在每种方法的顶部打开一个新连接,但它仍然声称连接保持打开状态并且数据库很忙,从而导致数据库锁定错误:

public void addTenant(String name, double leaseLength, boolean rentPaid, String propID, TableView table) {
    data = FXCollections.observableArrayList();
    try {
        //SQL FOR SELECTING ALL OF CUSTOMER
        String query = "INSERT INTO tenants VALUES (?,?,?,?)";
        //ResultSet
        PreparedStatement statement = c.prepareStatement(query);

        statement.setString(1, name);
        statement.setDouble(2, leaseLength);
        statement.setBoolean(3, rentPaid);
        statement.setString(4, propID);

        ResultSet rs = c.createStatement().executeQuery("SELECT * FROM tenants");

   
        for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) {
            //We are using non property style for making dynamic table
            final int j = i;
            TableColumn col = new TableColumn(rs.getMetaData().getColumnName(i + 1));
            col.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList, String>, ObservableValue<String>>() {
                public ObservableValue<String> call(TableColumn.CellDataFeatures<ObservableList, String> param) {
                    return new SimpleStringProperty(param.getValue().get(j).toString());
                }
            });
            col.setMinWidth(200);

            table.getColumns().addAll(col);
            System.out.println("Column [" + i + "] ");
        }
        while (rs.next()) {
            //Iterate Row
            ObservableList<String> row = FXCollections.observableArrayList();
            for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
                //Iterate Column
                row.add(rs.getString(i));
            }
            System.out.println("Row [1] added " + row);
            data.add(row);

        }

        //FINALLY ADDED TO TableView
        table.setItems(data);

    } catch (Exception e) {
        e.printStackTrace();
        System.out.println("Error on Building Data");
    }
}

这是一个从 TextFields 提取输入的单一功能按钮。这就是为什么在此处对查询进行硬编码的原因,而是从 TextField.getText() 方法中获取这些输入以用于各种输入,以将“租户”添加到表中。(想想租金管理系统。)最初准备好的语句之后的第二个 rs 是我尝试在添加后从表中获取新信息,以便在添加后可能重新填充表。我无法对此进行测试,因为我无法通过 Sqlite 数据库锁定错误

最后

这是我的表的屏幕截图,如果这有助于将其引入上下文,并且我需要在“添加”租户时更新所有表,但显然只有在添加按钮具有功能时,它当前由于数据库而不能锁定错误:

表格截图

标签: javasqlitejavafxjdbctableview

解决方案


推荐阅读