You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX CRUD应用新增数据未写入H2数据库问题求助

问题排查与解决方案

核心错误:误用executeQuery()执行INSERT语句

IDE提示的错误已经点明关键:executeQuery()仅用于执行查询类SQL(比如SELECT),执行INSERT/UPDATE/DELETE这类修改数据的语句,必须改用executeUpdate()方法。

修复后的addBtn方法(含参数绑定与资源优化)

@FXML
void addBtn(ActionEvent event) {
    String name = nameField.getText();
    String category = categoryField.getText();
    // 注意:原代码里的priceField.getAnchor()是错误写法,应该取输入文本转int
    int price;
    try {
        price = Integer.parseInt(priceField.getText());
    } catch (NumberFormatException e) {
        // 处理价格输入非数字的情况,比如弹出提示
        e.printStackTrace();
        return;
    }
    String date = "2023-01-01";

    // 用占位符?替代硬编码值,避免SQL注入,同时适配用户输入
    String query = "INSERT INTO DATA VALUES (?, ?, ?, ?)";

    // 使用try-with-resources自动关闭数据库资源,避免泄漏
    try (DBConnection dbConn = new DBConnection();
         Connection connection = dbConn.getConnection();
         PreparedStatement statement = connection.prepareStatement(query)) {

        // 绑定用户输入的参数到SQL语句
        statement.setString(1, name);
        statement.setString(2, category);
        statement.setInt(3, price);
        statement.setString(4, date);

        // 执行插入,获取受影响行数验证是否成功
        int affectedRows = statement.executeUpdate();
        if (affectedRows > 0) {
            // 数据库插入成功后再更新界面,保证数据一致
            Data data = new Data(name, category, price, date);
            table.getItems().add(data);
            // 可选:清空输入框提升体验
            nameField.clear();
            categoryField.clear();
            priceField.clear();
        }
    } catch (SQLException e) {
        e.printStackTrace();
        // 可选:弹出提示告知用户插入失败
    }
}

其他优化点

  1. 资源管理优化:原代码手动调用connection.close()容易在异常时导致资源泄漏,改用try-with-resources语法,JVM会自动关闭Connection、PreparedStatement这类实现AutoCloseable的资源。

  2. SQL注入防护:别直接拼接用户输入到SQL语句里,用PreparedStatement的参数绑定(setString/setInt)既安全又灵活。

  3. 初始化方法优化:同样把初始化逻辑改成try-with-resources,同时先设置列映射再加载数据:

@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
    fillTableWithData(); // 先配置列和数据类的映射关系
    try (DBConnection dbConn = new DBConnection();
         Connection connection = dbConn.getConnection();
         PreparedStatement statement = connection.prepareStatement("SELECT * FROM DATA");
         ResultSet result = statement.executeQuery()) {

        while(result.next()) {
            dataList.add(new Data(
                    result.getString("name"),
                    result.getString("category"),
                    result.getInt("price"),
                    result.getString("date"))
            );
        }
        table.setItems(dataList);
    } catch(SQLException e) {
        e.printStackTrace();
    }
}
  1. 数据一致性保障:只有当数据库插入成功后,再把数据添加到界面表格,避免出现“界面显示了但数据库没保存”的情况。

验证步骤

  1. 替换executeQuery()为executeUpdate()。
  2. 修正price字段的获取逻辑,添加输入合法性校验。
  3. 用参数占位符替换硬编码的VALUES值。
  4. 启动程序测试新增功能,通过H2控制台查看数据库是否同步新增数据。

内容的提问来源于stack exchange,提问作者Damian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 17:15:30