Eclipse开发优惠券项目时查询客户已购优惠券列表返回空的问题
问题根因
- 占位符完全未生效
你使用普通Statement执行带?占位符的SQL,Statement不会解析占位符,会直接把'?'当成字符串值去匹配int类型的CUSTOMER_ID字段,根本匹配不到任何数据,因此优惠券ID集合为空,后续循环逻辑完全不执行,最终返回空列表。 - 查询目标表错误
就算第一步能查到优惠券ID,你后续的SQL仍然查询只有两个外键字段的customers_vs_coupons关联表,这个表没有Coupon实体需要的分类、标题、价格等业务字段,无法组装成优惠券实体。 - 潜在风险:
拼接SQL有注入风险,未关闭Statement/ResultSet资源、未在异常分支归还连接,容易造成连接池泄漏。
修复方案
直接用联表查询一次完成数据获取,减少数据库交互次数,同时解决占位符、表查询错误的问题,示例代码如下:
@Override public List<Coupon> getPurchasedCoupons(int customerID) throws SQLException { List<Coupon> customerCoupons = new ArrayList<>(); Connection connection = null; // 联表查询关联表和优惠券主表,直接取需要的所有字段 String sql = "SELECT c.COUPON_ID, c.COMPANY_ID, c.CATEGORY_ID, c.TITLE, c.DESCRIPTION, " + "c.START_DATE, c.END_DATE, c.AMOUNT, c.PRICE, c.IMAGE " + "FROM couponsystem.customers_vs_coupons cv " + "INNER JOIN couponsystem.coupons c ON cv.COUPON_ID = c.COUPON_ID " + "WHERE cv.CUSTOMER_ID = ?"; try { connection = pool.getConnection(); // 用PreparedStatement处理占位符,避免注入 PreparedStatement pstmt = connection.prepareStatement(sql); // 绑定客户ID参数,替换? pstmt.setInt(1, customerID); ResultSet rs = pstmt.executeQuery(); while (rs.next()) { Coupon coupon = new Coupon( rs.getInt("COUPON_ID"), rs.getInt("COMPANY_ID"), Category.categoryFor(rs.getInt("CATEGORY_ID")), rs.getString("TITLE"), rs.getString("DESCRIPTION"), rs.getDate("START_DATE"), rs.getDate("END_DATE"), rs.getInt("AMOUNT"), rs.getDouble("PRICE"), rs.getString("IMAGE") ); customerCoupons.add(coupon); } // 关闭资源 rs.close(); pstmt.close(); } finally { // 无论是否报错,都归还连接到连接池 if (connection != null) { ConnectionPool.getInstance().restoreConnection(connection); } } return customerCoupons; }
注意:SQL中的字段名要和你数据库实际的字段名完全对应,如果你的优惠券表主键不是
COUPON_ID,需要对应调整字段名。
内容的提问来源于stack exchange,提问作者Daniel R
相关产品推荐
相关产品推荐

