为了账号安全,请及时绑定邮箱和手机立即绑定

使用 Spring Data JPA 处理 POST 请求中的关系

使用 Spring Data JPA 处理 POST 请求中的关系

九州编程 2021-10-13 12:49:35
我有以下实体,CrudRepository每个实体都有一个:@Entityclass Movie {    @Id Long id;    @Column String name;    @ManyToOne Person director;}@Entityclass Person {    @Id Long id;    @Column String name;}我的控制器看起来像这样:@RestController@RequestMapping("/movies")class MovieController {    private MovieRepository movies = ...;    private PersonRepository people = ...;    @PostMapping    public Movie create(@RequestBody MovieRequest request) {        // Get the director        Person director = people.findById(request.directorId);        // Create the new movie        Movie movie = new Movie();        movie.name = request.name;        movie.director = director;       // Save the new movie       return movies.save(movie);    }}class MovieRequest {    String name;    Long directorId}如您所见,该create方法首先通过其 id 加载导演,然后创建新电影并最后保存它。这会导致两次访问数据库:第一次检索导演,第二次保存电影。在这种情况下,这不是什么大问题,但可能存在具有很多关系的实体,这意味着可能会执行大量查询来实现单个插入。问题:我想在单个数据库操作中保存新电影。有没有办法避免初始人员查询?有没有更好的方法来处理这样的情况?
查看完整描述

3 回答

?
函数式编程

TA贡献1807条经验 获得超9个赞

没有办法告诉代码Person它需要与您的新Movie. 因此,您确实需要执行查询并手动进行关联。

只有当您的端点Person在创建Movie. 然后您可以简单地执行 2 个保存操作或使用 aCascadeType=ALL进行单个保存操作。


如果您能够更改请求参数,那么接收完整Person对象而不是接受directorId. 这样你就可以建立关联movie.director = director;

小心这种类似的方法:如果接收到的Person对象没有存储在您的数据库中,您将收到一个异常。


也许您可以为您的Directors. 例如,如果您将所有 Director 都保存在 Redis 中,则可以搜索Director与接收到的对应directorId的然后执行关联。

当然,您仍然需要进行第二次操作,但它可能比查询数据库便宜得多。


查看完整回答
反对 回复 2021-10-13
?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

这会很丑,但你的请求中有 personId,所以你可以用你的长 personId 映射你的电影


class Movie {

    @Id Long id;

    @Column String name;

    @ManyToOne Person director;


    @Column(name="PERSON_ID")

    long personId;

}

在你的控制器中


movie.setPersonId(request.directorId);


查看完整回答
反对 回复 2021-10-13
  • 3 回答
  • 0 关注
  • 175 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信