如何选择多对多关系数据删除方法及编写Spring Controller
解决Controller获取请求体及多对多关系删除问题
一、修正Controller代码以获取请求体
你当前的Controller存在路径参数与请求体不匹配、未正确接收JSON请求的问题,以下是修正方案:
1. 创建请求体接收DTO
先定义一个对应请求体格式的DTO类,用于绑定JSON参数:
public class DeleteTransactionRequest { private Integer userid; private List<String> transaction; // 自动生成Getter、Setter方法 }
2. 编写正确的Controller方法
调整请求映射注解,用@RequestBody接收请求体,并调用Service层处理业务:
@DeleteMapping("/remove") public ResponseEntity<Void> deleteTransactionsByUserId(@RequestBody DeleteTransactionRequest request) { transactionService.deleteUserTransactions(request.getUserid(), request.getTransaction()); return ResponseEntity.noContent().build(); }
- 用
@RequestBody直接绑定JSON请求体到DTO类,可直接获取userid和交易列表 - 删除路径中多余的
{id}参数,所有参数从请求体读取 - 返回
ResponseEntity<Void>符合REST规范,204状态码表示删除操作成功且无返回内容
二、多对多关系删除的最优方法
根据业务场景和数据量,推荐以下几种方案:
1. JPA实体关联操作(规范优先)
若实体类已配置多对多关联(如User与Transaction),可直接通过实体集合操作:
// Service层示例代码 @Transactional public void deleteUserTransactions(Integer userId, List<String> transactionCodes) { User user = userRepository.findById(userId) .orElseThrow(() -> new RuntimeException("用户不存在")); // 从用户的交易集合中移除指定项 user.getTransactions().removeIf(t -> transactionCodes.contains(t.getCode())); // JPA持久化上下文会自动同步中间表,无需手动操作 userRepository.save(user); }
这种方式符合ORM规范,代码简洁,框架自动处理中间表删除逻辑。
2. 原生SQL批量删除(性能优先)
针对大数据量批量删除场景,直接执行原生SQL跳过实体加载,性能更优:
// Service层示例代码 @Transactional public void deleteUserTransactions(Integer userId, List<String> transactionCodes) { String sql = "DELETE FROM user_transaction WHERE user_id = ?1 AND transaction_code IN (?2)"; entityManager.createNativeQuery(sql) .setParameter(1, userId) .setParameter(2, transactionCodes) .executeUpdate(); }
注意替换中间表名和字段名为实际业务中的对应名称。
3. Spring Data JPA自定义删除方法
在Repository接口中定义自定义方法,由框架自动生成SQL:
public interface UserTransactionRepository extends JpaRepository<UserTransaction, Long> { @Modifying @Transactional void deleteByUseridAndTransactionIn(Integer userid, List<String> transaction); }
Service层直接调用该方法即可,无需手动编写SQL。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

