JavaFX:清空SQLite查询ResultSet以避免保留历史结果
解决ComboBox2保留旧查询结果的问题
嘿,我一眼就发现问题所在了——你每次调用populateFlavourCombos()给flavourOne添加新数据前,没有清空它已有的items集合!这就导致每次选择新品牌时,旧的口味数据都被保留下来,和新数据叠加在一起,自然就出现了结果总和的情况。
最直接的修复方法
在populateFlavourCombos()方法里,开始添加新数据之前,先清空flavourOne的items:
@FXML public void populateFlavourCombos() { selectedBrand = brandOne.valueProperty().getValue().toString(); // 先清空旧数据! flavourOne.getItems().clear(); try { con = DriverManager.getConnection("jdbc:sqlite:C:\\Users\\PengStation420\\IdeaProjects\\PengVapour\\PVIM.sqlite"); ResultSet rs = con.createStatement().executeQuery("SELECT " + "DISTINCT Flavour " + "FROM Concentrates " + "WHERE Concentrates.Brand " + "LIKE '%" + selectedBrand + "%'"); int rows = 0; while (rs.next()) { flavoursInInventory = rs.getString("Flavour"); flavourOne.getItems().addAll(flavoursInInventory); rows++; } flavourOne.setVisibleRowCount(rows); // 别忘了关闭ResultSet、Statement和Connection! rs.close(); con.close(); } catch (SQLException ex) { Logger.getLogger(InventoryController.class.getName()).log(Level.SEVERE, null, ex); } }
额外的代码优化建议
除了清空items,你的代码还有几个可以优化的地方,能避免潜在问题:
- 复用数据库连接,避免重复创建:每次查询都新建连接是低效且容易导致资源泄漏的,建议在initialize时创建一次连接,或者使用连接池,用完记得关闭。
- 使用PreparedStatement防止SQL注入:直接拼接SQL字符串会有注入风险,改用预编译语句更安全:
String sql = "SELECT DISTINCT Flavour FROM Concentrates WHERE Brand LIKE ?"; PreparedStatement pstmt = con.prepareStatement(sql); pstmt.setString(1, "%" + selectedBrand + "%"); ResultSet rs = pstmt.executeQuery(); - 用try-with-resources自动关闭资源:可以不用手动写close(),Java会自动帮你关闭ResultSet、Statement、Connection:
try (Connection con = DriverManager.getConnection(...); PreparedStatement pstmt = con.prepareStatement(sql); ResultSet rs = pstmt.executeQuery()) { // 处理结果集 } catch (SQLException ex) { // 异常处理 } - 空值判断更严谨:比如
selectedBrand != ""可以改成selectedBrand != null && !selectedBrand.isEmpty(),避免空指针。
优化后的完整populateFlavourCombos示例
@FXML public void populateFlavourCombos() { selectedBrand = brandOne.valueProperty().getValue().toString(); if (selectedBrand == null || selectedBrand.isEmpty()) { flavourOne.getItems().clear(); return; } flavourOne.getItems().clear(); String sql = "SELECT DISTINCT Flavour FROM Concentrates WHERE Brand LIKE ?"; try (Connection con = DriverManager.getConnection("jdbc:sqlite:C:\\Users\\PengStation420\\IdeaProjects\\PengVapour\\PVIM.sqlite"); PreparedStatement pstmt = con.prepareStatement(sql)) { pstmt.setString(1, "%" + selectedBrand + "%"); try (ResultSet rs = pstmt.executeQuery()) { int rows = 0; while (rs.next()) { flavoursInInventory = rs.getString("Flavour"); flavourOne.getItems().add(flavoursInInventory); // 用add()代替addAll(),因为是单个元素 rows++; } flavourOne.setVisibleRowCount(rows); } } catch (SQLException ex) { Logger.getLogger(InventoryController.class.getName()).log(Level.SEVERE, null, ex); } }
这样修改后,每次选择新品牌时,flavourOne都会先清空旧数据,再加载对应品牌的新口味,就不会出现叠加的问题啦!
内容的提问来源于stack exchange,提问作者disco420
相关产品推荐
相关产品推荐

