使用JDBC删除一对多关联表数据遇参数错误,求解决方案
JDBC处理一对多关联数据删除的解决方案
错误原因分析
你遇到的No value supplied for the SQL parameter 'users_give_id'错误,并非删除语句的问题——你的删除SQL用的是占位符?,参数传递逻辑正确。问题出在你调用的get(id)方法:该方法大概率使用了NamedParameterJdbcTemplate,且SQL语句中包含命名参数:users_give_id,但调用时只传入了id,未提供users_give_id参数,导致抛出该错误。
正确的关联删除实现逻辑
针对你的Users(父表)和Give(子表,通过users_give_id关联)的一对多场景,删除子表(Give)记录无需额外处理父表,只需确保删除的记录属于当前用户(避免越权)即可。完整实现步骤如下:
1. 新增带用户验证的查询方法
先实现一个能同时验证记录归属的查询方法,避免查询不属于当前用户的记录:
public Give getGiveByIdAndUserId(Long id, Long userId) { String query = "SELECT id, date, type, amount, amount_type, description, img_url, location, status, users_give_id " + "FROM Give WHERE id = ? AND users_give_id = ?"; return jdbc.getJdbcTemplate().queryForObject( query, new BeanPropertyRowMapper<>(Give.class), id, userId ); }
2. 修正删除方法逻辑
修改deleteGive方法,先通过带用户验证的查询确认记录存在且归属当前用户,再执行删除:
@Override public Give deleteGive(Long id, Long userId) { try { // 先查询待删除记录,同时验证归属当前用户 Give giveToDelete = getGiveByIdAndUserId(id, userId); // 执行删除操作 String deleteQuery = "DELETE FROM Give WHERE id = ? AND users_give_id = ?"; int rowsAffected = jdbc.getJdbcTemplate().update(deleteQuery, id, userId); // 处理并发删除场景 if (rowsAffected == 0) { throw new ApiException("Give record was already deleted by another operation"); } return giveToDelete; } catch (EmptyResultDataAccessException exception) { throw new ApiException("No Give record found with id: " + id + " for current user"); } catch (Exception exception) { log.error("Delete Give failed: {}", exception.getMessage(), exception); throw new ApiException("Failed to delete Give. Please try again later."); } }
3. 控制器层保持原有逻辑即可
你的控制器方法无需修改,确保UserDTO能正确获取当前登录用户ID即可。
一对多关联删除的通用规则
删除子表记录(如Give)
直接删除子表记录,只需通过关联字段(users_give_id)过滤归属,避免越权,无需处理父表。
删除父表记录(如Users)
由于外键约束,必须先删除该父表关联的所有子表记录,再删除父表:
public void deleteUser(Long userId) { // 第一步:删除该用户下所有Give记录 String deleteGivesSql = "DELETE FROM Give WHERE users_give_id = ?"; jdbc.getJdbcTemplate().update(deleteGivesSql, userId); // 第二步:删除用户记录 String deleteUserSql = "DELETE FROM Users WHERE id = ?"; int rowsAffected = jdbc.getJdbcTemplate().update(deleteUserSql, userId); if (rowsAffected == 0) { throw new ApiException("No User found with id: " + userId); } }
内容的提问来源于stack exchange,提问作者Ilze
相关产品推荐
相关产品推荐

