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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 14:55:09