Spring Boot单向一对多关联:Rest接口同时保存用户与借阅书籍
Spring Boot 单向一对多关联的Rest接口数据保存实现
1. 确认实体类关联配置
确保你的User和BorrowedBooks实体类的单向一对多关联配置正确,核心是通过级联操作实现用户与书籍数据的同步保存:
@Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; // 单向一对多关联,级联所有操作,orphanRemoval确保删除用户时自动清理关联书籍 @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) @JoinColumn(name = "user_id") // 指定BorrowedBooks表中的外键字段 private List<BorrowedBooks> borrowedBooks = new ArrayList<>(); // 省略getter、setter、构造方法 } @Entity public class BorrowedBooks { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String bookName; private String genre; // 单向关联无需添加User字段 // 省略getter、setter、构造方法 }
2. 创建请求DTO
定义DTO接收Postman传递的组合参数,避免直接暴露实体类结构:
// 接收用户+借阅书籍的请求DTO public class UserBorrowRequest { private Long userId; // 可选:存在则更新用户,不存在则创建新用户 private String userName; private List<BorrowedBookDTO> borrowedBooks; // 省略getter、setter } // 书籍信息DTO public class BorrowedBookDTO { private String bookName; private String genre; // 省略getter、setter }
3. 编写业务逻辑(Service层)
复刻Hibernate的对象创建逻辑,处理用户的创建/更新,以及书籍实体的转换与关联:
@Service public class UserService { private final UserRepository userRepository; // 构造注入替代@Autowired public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public User saveUserWithBorrows(UserBorrowRequest request) { User user; // 处理用户逻辑:存在则查询并更新,不存在则创建新用户 if (request.getUserId() != null) { user = userRepository.findById(request.getUserId()) .orElseThrow(() -> new IllegalArgumentException("指定用户不存在")); user.setName(request.getUserName()); } else { user = new User(); user.setName(request.getUserName()); } // 将DTO转换为BorrowedBooks实体 List<BorrowedBooks> bookEntities = request.getBorrowedBooks().stream() .map(dto -> { BorrowedBooks book = new BorrowedBooks(); book.setBookName(dto.getBookName()); book.setGenre(dto.getGenre()); return book; }) .collect(Collectors.toList()); // 若需替换用户现有借阅记录,先清空集合再添加;若需追加则直接调用addAll user.getBorrowedBooks().clear(); user.getBorrowedBooks().addAll(bookEntities); // 保存用户,通过级联操作自动保存关联书籍 return userRepository.save(user); } }
4. 编写Rest Controller
提供接口接收Postman的请求:
@RestController @RequestMapping("/api/users") public class UserController { private final UserService userService; public UserController(UserService userService) { this.userService = userService; } @PostMapping("/borrow") public ResponseEntity<User> handleUserBorrow(@RequestBody UserBorrowRequest request) { User savedUser = userService.saveUserWithBorrows(request); return ResponseEntity.ok(savedUser); } }
5. Postman请求示例
发送POST请求到http://localhost:8080/api/users/borrow,请求体为JSON格式:
{ "userId": 1, // 可选,不传则创建新用户 "userName": "张三", "borrowedBooks": [ { "bookName": "Spring Boot实战", "genre": "计算机技术" }, { "bookName": "百年孤独", "genre": "文学" } ] }
关键注意事项
- 必须确保
User类的@OneToMany注解设置了cascade = CascadeType.ALL,否则保存用户时不会自动同步书籍数据 - 若需要更新用户的借阅记录,记得先清空现有集合再添加新数据,避免重复追加
- 异常处理可根据业务需求扩展,比如通过全局异常处理器返回统一格式的错误响应
内容的提问来源于stack exchange,提问作者Mathew Pius
相关产品推荐
相关产品推荐

