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

标签 java spring spring-mvc spring-data-jpa spring-data

我有以下实体,每个实体都有一个 CrudRepository:

@Entity
class Movie {
    @Id Long id;
    @Column String name;
    @ManyToOne Person director;
}

@Entity
class Person {
    @Id Long id;
    @Column String name;
}

我的 Controller 看起来像这样:

@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 加载导演,然后创建新电影,最后保存它。这导致两次访问数据库:第一次检索导演,第二次保存电影。

在这种情况下,这不是什么大问题,但可能存在一个具有很多关系的实体,这意味着可能需要进行大量查询才能实现单个插入。

问题:我想在单一数据库操作中保存新电影。有没有办法避免最初的人查询?有没有更好的方法来处理这种情况?

最佳答案

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

只有当您的端点在创建 Movie 的同时创建 Person 时,才有可能使用另一种方法。然后您可以简单地执行 2 个保存操作或使用 CascadeType=ALL 进行单个保存操作。


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

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


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

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

关于java - 使用 Spring Data JPA 处理 POST 请求中的关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52519586/

相关文章:

java - 如何按字母顺序对哈希表中的元素进行排序?

java - 在 Spring 3.1.0 中使用 Spring Data JPA

java - GORM/Grails 中的家谱模型?

java - CronSequenceGenerator 的解决方法是每月的最后一天?

java - 包 org.springframework.web.bind.annotation 不存在,即使它是在 POM 中定义的

java - 如何使用进程在目录中运行 jar 文件

java - 绕圈发射弹丸

java - 启动时设置tomcat初始连接池

spring - 使用 spring 和 junit 测试 Web 应用程序集群

java - PropertySources 中各种源的优先级