我有以下实体,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
的然后执行关联。
当然,您仍然需要进行第二次操作,但它可能比查询数据库便宜得多。
尚方宝剑之说
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);
添加回答
举报
0/150
提交
取消