Java Springboot JpaRepository 可以动态加载关系数据吗
问题
我遵循了几个教程,发现每次我向服务器发出 HTTP 请求时,JpaRepository 都会返回实体及其所有关系。
以下是代码
@Table(name = "provinces")
public class Province {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(nullable = false)private Long id;private String name;@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)@JoinColumn(name = "province_id")private List<City> cities;@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)@JoinColumn(name = "province_id")private List<PreRelease> preReleases;@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)@JoinColumn(name = "province_id")private List<Project> projects;
}
@Table(name = "cities")
public class City {@ManyToOne(fetch = FetchType.LAZY)@JoinColumn(name = "province_id")private Province province;@OneToMany(fetch = FetchType.LAZY)@JoinColumn(name = "city_id")private List<Project> projects;
}
public class Project {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(nullable = false)private Integer id;@ManyToOne(fetch = FetchType.LAZY)@JoinColumn(name = "province_id")private Province province;@ManyToOne(fetch = FetchType.LAZY)@JoinColumn(name = "city_id")private City city;@ManyToOne(fetch = FetchType.LAZY)@JoinColumn(name = "pre_release_id")private PreRelease preRelease;
}
问题是:JpaRepository 能否动态加载关系数据,有时我确实想要它的关系,有时我不想要它的关系数据。
解答
首先,只有当您尝试访问相关实体时,才会加载它们,因为您fetch = FetchType.LAZY
在关系中定义了
此外,这取决于你所说的关系。如果你的意思是只想加载相关实体的 id 而不是整个实体,我建议这样做(自 JAVA 17 起重要记录可用):
@Query(SELECT new com.baeldung.jpa.records.ProjectRecord(p.id, p.province.id, p.city.id, p.preRelease.id) FROM Project p WHERE b.id = :id")
ProjectRecord findProjectById(@Param("id") Long id);
在存储库中使用此注释仅选择 id 并将其写入单独的模型,因此它不会加载所有相关实体。如果这不起作用,也许尝试在 @Query 中使用 nativeQuery=true 并从 JPQL 查询切换到本机 SQL:) https://www.baeldung.com/spring-jpa-java-records
或者你也可以使用@JsonIgnore
从数据库获取数据时要忽略的属性。
例如:
@Table(name = "cities")
public class City {@ManyToOne(fetch = FetchType.LAZY)@JoinColumn(name = "province_id")private Province province;@JsonIgnore //To ignore projects while fetching the data@OneToMany@JoinColumn(name = "city_id")private List<Project> projects;
}