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
相关产品推荐
相关产品推荐

