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(); // 可选:弹出提示告知用户插入失败 } }
其他优化点
资源管理优化:原代码手动调用
connection.close()容易在异常时导致资源泄漏,改用try-with-resources语法,JVM会自动关闭Connection、PreparedStatement这类实现AutoCloseable的资源。SQL注入防护:别直接拼接用户输入到SQL语句里,用PreparedStatement的参数绑定(
setString/setInt)既安全又灵活。初始化方法优化:同样把初始化逻辑改成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(); } }
- 数据一致性保障:只有当数据库插入成功后,再把数据添加到界面表格,避免出现“界面显示了但数据库没保存”的情况。
验证步骤
- 替换
executeQuery()为executeUpdate()。 - 修正price字段的获取逻辑,添加输入合法性校验。
- 用参数占位符替换硬编码的VALUES值。
- 启动程序测试新增功能,通过H2控制台查看数据库是否同步新增数据。
内容的提问来源于stack exchange,提问作者Damian
相关产品推荐
相关产品推荐

