JavaFX ListView删除标签后出现查询无结果错误的原因排查
问题分析与解决方案
核心错误原因
错误提示"No results were returned by the query." 90%概率是你的**removeTag方法误用了SQL执行方式**:
DELETE属于数据修改语句(DML),必须通过executeUpdate()执行,但如果你的removeTag里用了executeQuery()来执行DELETE操作,PostgreSQL就会抛出这个错误——因为DELETE不会返回结果集,而executeQuery()强制要求查询必须返回结果集。
代码里的其他冗余/风险问题
除了removeTag的核心问题,你的删除逻辑还有重复操作,可能引发额外混乱:
- 删除按钮事件中,你同时执行了
list.remove(...)、listView.getItems().remove(tag)和refreshTags(),前两个操作完全多余——refreshTags()会重新从数据库加载数据并覆盖ListView的项,重复删除本地数据只会导致视图状态不一致。 - 直接拼接SQL字符串
"SELECT * FROM tags WHERE user_id = " + user.getId()存在SQL注入风险,必须用PreparedStatement替代Statement。
具体修复步骤
修正
removeTag方法
把执行DELETE的代码改成用executeUpdate(),同时改用PreparedStatement避免注入:public void removeTag(int userId, String tagName) throws SQLException { String sql = "DELETE FROM tags WHERE user_id = ? AND name = ?"; try (Connection conn = connection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setInt(1, userId); pstmt.setString(2, tagName); pstmt.executeUpdate(); // 关键:用executeUpdate而非executeQuery } }简化删除按钮的事件逻辑
只保留删除数据库记录和刷新列表的操作,去掉冗余的本地列表删除:deleteButton.setOnAction(actionEvent -> { try { removeTag(user.getId(), tag.getName()); refreshTags(); } catch (SQLException e) { // 建议用Alert弹窗提示用户,而非直接抛出RuntimeException Alert alert = new Alert(Alert.AlertType.ERROR); alert.setTitle("删除失败"); alert.setContentText("无法删除标签:" + e.getMessage()); alert.showAndWait(); } });修复
refreshTags的SQL注入问题
改用PreparedStatement,同时用clear()替代removeAll(),代码更清晰:private void refreshTags(){ listView.getItems().clear(); try { String query = "SELECT * FROM tags WHERE user_id = ?"; try (Connection connection = connection(); PreparedStatement pstmt = connection.prepareStatement(query)) { pstmt.setInt(1, user.getId()); ResultSet resultSet = pstmt.executeQuery(); while (resultSet.next()) { listView.getItems().add(new Tag( user.getId(), resultSet.getString("name"), resultSet.getString("color")) ); } } } catch (SQLException e) { throw new RuntimeException(e); } }修复初始化块的潜在空指针问题
你的listOfTags初始化代码如果listOfTags()返回null会触发NPE,建议加空判断:{ try { List<Tag> tempTags = listOfTags(); listOfTags = tempTags != null ? new ArrayList<>(tempTags) : new ArrayList<>(); } catch (SQLException e) { throw new RuntimeException(e); } }
内容的提问来源于stack exchange,提问作者MsLaus
相关产品推荐
相关产品推荐

