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

Java Swing调用SQLite多条件搜索结果异常问题求助

问题分析与解决方案

你的核心问题出在三个地方:LIKE操作符未使用通配符、空输入未做处理、SQL语句拼接逻辑不合理,同时还存在SQL注入风险,逐个解决就能修复多条件搜索的问题:

1. 缺失LIKE通配符导致匹配逻辑错误

你当前的LIKE语句是v.make LIKE '" + make + "',这种写法只会匹配完全等于输入内容的记录,而非模糊搜索。比如输入"Ford",只会找到make字段完全是"Ford"的记录,而不是包含"Ford"的。单条件搜索时可能刚好输入了完全匹配的值,所以看似正常,但组合条件时就会出现偏差。

正确的模糊搜索需要在匹配值前后加上%通配符,比如v.make LIKE '%Ford%',表示匹配包含"Ford"的任意字符串。

2. 空输入未处理导致AND/OR逻辑失效

当你只填写一个条件,另一个输入框为空时:

  • 用AND的话,空输入会生成v.make LIKE '' AND t.test_result LIKE 'Pass',LIKE ''只会匹配字段为空的记录,自然无结果返回;
  • 用OR的话,空输入会生成v.make LIKE '' OR t.test_result LIKE 'Pass',会把所有make字段为空的记录也查出来,导致结果偏差。

解决方法是动态构建WHERE子句:只有当输入框内容不为空时,才将该条件加入查询。

3. 使用Statement拼接SQL存在注入风险

直接拼接字符串生成SQL语句,不仅容易出错,还存在SQL注入漏洞,应该改用PreparedStatement预编译语句,既安全又能避免字符串拼接的语法错误。

修正后的代码示例

重点修改按钮点击事件中的查询逻辑:

bMake.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        String make = tf1.getText().trim();
        String testResult = tf4.getText().trim();
        // 动态构建SQL和参数列表
        StringBuilder sqlBuilder = new StringBuilder("SELECT DISTINCT * FROM Vehicle v JOIN Test t ON v.vehicle_id = t.vehicle_id WHERE 1=1");
        List<String> params = new ArrayList<>();

        if (!make.isEmpty()) {
            sqlBuilder.append(" AND v.make LIKE ?");
            params.add("%" + make + "%"); // 添加通配符实现模糊搜索
        }
        if (!testResult.isEmpty()) {
            sqlBuilder.append(" AND t.test_result LIKE ?");
            params.add("%" + testResult + "%");
        }

        try (Connection c = DriverManager.getConnection("jdbc:sqlite:./data/Tables.db");
             PreparedStatement pstmt = c.prepareStatement(sqlBuilder.toString())) {
            // 设置参数
            for (int i = 0; i < params.size(); i++) {
                pstmt.setString(i + 1, params.get(i));
            }

            ResultSet rs = pstmt.executeQuery();
            dtm.setRowCount(0);
            while (rs.next()) {
                int ID = rs.getInt("vehicle_ID");
                String make_ = rs.getString("make");
                String model_ = rs.getString("model");
                String colour = rs.getString("colour");
                String fuel = rs.getString("fuel_type");
                String cylinder = rs.getString("cylinder_capacity");
                String use = rs.getString("first_use");
                int test_id = rs.getInt("test_id");
                String test_type = rs.getString("test_type");
                String test_class = rs.getString("test_class");
                String test_date = rs.getString("test_date");
                String test_result = rs.getString("test_result");
                String test_mileage = rs.getString("test_mileage");
                // 注意这里要用结果集的make_,而不是用户输入的make
                dtm.addRow(new Object[]{ID, make_, model_, colour, fuel, cylinder, use,
                        test_id, test_type, test_class, test_date, test_result, test_mileage});
            }
        } catch (SQLException e1) {
            e1.printStackTrace();
        }
    }
});

额外注意点

  • 代码中你原本在addRow时用了用户输入的make,而不是从结果集获取的make_,这会导致显示错误(比如模糊搜索时,显示的是输入的关键词而非数据库实际值),已经在修正代码中改过来了;
  • 1=1是动态构建WHERE子句的常用技巧,保证即使没有任何条件,SQL语法依然合法;
  • 使用try-with-resources语句自动关闭Connection和PreparedStatement,避免资源泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 04:37:45