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

Java JDBC查询报Column 'risk_id' not found异常排查

雷达图数据查询功能问题修复

问题根因

你遇到的两个核心报错/异常都来自代码实现的逻辑错误,和数据库字段本身无关:

  • Column 'risk_id' not found报错:遍历risks_to_assets表查询结果集rs1时,错用了外层查询assets表的结果集rs取risk_id字段。rs结果集仅返回id一个字段,不存在risk_id列,必然抛出该异常。
  • assets表仅返回2条数据:JDBC默认规则下,同一个Connection创建新的Statement执行查询时,会自动关闭之前Statement关联的ResultSet。你在外层遍历assets结果集rs的循环中,嵌套创建ps1/ps2/ps3多次执行新查询,第一次执行ps1时就会关闭外层的rs,导致遍历提前终止,无法返回全量资产。
  • 原设计的分层嵌套查询逻辑本身存在明显缺陷:
    • 属于典型的N+1查询反模式,资产量、关联风险量上升后,SQL请求数会指数级增长,性能极差
    • 直接拼接参数到SQL字符串,没有使用PreparedStatement参数占位,存在SQL注入风险
    • 每完成一层字段查询就往返回列表add一次同一个risk对象,会导致单条数据重复插入多次,返回结果存在大量冗余

修复方案

直接用单条LEFT JOIN连表SQL一次拉取所有需要的字段,完全去掉嵌套查询,从根源解决上述所有问题。

优化后的查询SQL

SELECT 
  a.id AS asset_id,
  rta.risk_id,
  rs.calculated_risk,
  m.mitigation_percent
FROM assets a
LEFT JOIN risks_to_assets rta ON a.id = rta.asset_id
LEFT JOIN risk_scoring rs ON rta.risk_id = rs.id
LEFT JOIN mitigations m ON rta.risk_id = m.risk_id

修复后的Java实现代码

public ArrayList<risk> getGet_all_risk_for_radar_chart() throws Exception {
    ArrayList<risk> rr = new ArrayList<>();
    // 使用try-with-resources自动关闭连接、语句、结果集,避免资源泄漏
    try (
        DB_connection1 obj_DB_connection = new DB_connection1();
        Connection connection = obj_DB_connection.get_connection();
        PreparedStatement ps = connection.prepareStatement(
            "SELECT " +
            "  a.id AS asset_id, " +
            "  rta.risk_id, " +
            "  rs.calculated_risk, " +
            "  m.mitigation_percent " +
            "FROM assets a " +
            "LEFT JOIN risks_to_assets rta ON a.id = rta.asset_id " +
            "LEFT JOIN risk_scoring rs ON rta.risk_id = rs.id " +
            "LEFT JOIN mitigations m ON rta.risk_id = m.risk_id"
        );
        ResultSet rs = ps.executeQuery();
    ) {
        while (rs.next()) {
            risk r = new risk();
            r.setId(rs.getInt("asset_id"));
            int riskId = rs.getInt("risk_id");
            // 处理资产未关联风险的空值场景
            if (!rs.wasNull()) {
                r.setRisk_id(riskId);
                r.setCalculated_risk(rs.getInt("calculated_risk"));
                r.setMitigation_percent(rs.getInt("mitigation_percent"));
            }
            // 单条记录仅插入一次,避免冗余
            rr.add(r);
        }
    } catch (Exception e) {
        e.printStackTrace();
        throw e;
    }
    return rr;
}

修复效果

  • 彻底解决字段不存在、资产数据查询不全的报错
  • 数据库交互从原来的N次嵌套请求降低为1次请求,查询性能提升明显
  • 无SQL注入风险,JDBC资源自动释放,不会出现连接泄漏
  • 返回结果无重复冗余数据,可直接用于雷达图渲染

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 19:48:28