我最近从JEE切换到Spring Boot,到目前为止我很喜欢它。 但我遇到了一个小问题。我有这个方法来获取过去看起来像这样的惰性引用:
public Foo getParentWithChildren(long id, boolean isFetchChild, boolean isFetchPets) {
StringBuilder sql = new StringBuilder();
sql.append("select DISTINCT(p) from Parent p");
if(isFetchChild) {
sql.append(" left join p.child c");
} if(isFetchPets) {
sql.append(" left join p.pets pts");
}
sql.append(" where p.id=:id");
TypedQuery<Foo> query = em.createQuery(sql.toString(), Foo.class);
query.setParameter("id", id);
return query.getSingleResult();
}
现在有了spring数据和他们非常棒的接口,我想在界面上使用@Query注释做一些类似的事情而不必编写自定义实现。但是只使用界面可以做类似的事情。
下面的示例显然不起作用,但我希望您了解我想要实现的目标
@Query("select distinct(p) from Parent p " +
(fetchChild ? " left join p.child c" : "") +
(fetchPets ? " left join p.pets pts" : "") +
" where p.id=:id")
Foo getParentWithChildren(@Param("id") long id, @Param("fetchChild") boolean isFetchChild, @Param("fetchPets") boolean isFetchPets);
我有类似的可能吗?
答案 0 :(得分:1)
您可以在界面中创建多个方法,并使用JPA 2.1中引入的EntityGraph功能,Spring Data JPA以各种方式支持这些功能:
http://docs.spring.io/spring-data/jpa/docs/1.11.0.RELEASE/reference/html/#jpa.entity-graph
public interface FooRepository extends JpaRepository<Foo, Long>{
@EntityGraph(attributePaths = { "children" })
@Query("select f from Foo f where f.id = :id")
Foo getFooWithChildren(@Param("id") long id);
@EntityGraph(attributePaths = { "pets" })
@Query("select f from Foo f where f.id = :id")
Foo getFooWithPets(@Param("id") long id);
@EntityGraph(attributePaths = { "children", "pets" })
@Query("select f from Foo f where f.id = :id")
Foo getFooWithChildrenAndPets(@Param("id") long id);
}
这个问题是您需要为每个方法重复查询。能够将实体图作为参数传递给查询方法似乎是Spring Data JPA模块中缺少的有用功能。
我前一段时间在门票上提出但尚未更新:
https://jira.spring.io/browse/DATAJPA-645?filter=-2
此问题的答案中的链接Spring Data JPA And NamedEntityGraphs会建议在下方进行扩展,以便我们完成此操作:
https://github.com/Cosium/spring-data-jpa-entity-graph
使用此扩展程序,代码简化为:
public interface FooRepository extends JpaEntityGraphRepository<Foo, Long>{
}
并将其命名为:
Foo foo = fooRepository.findOne(1L,
new DynamicEntityGraph(Arrays.asList({"children");
Foo foo = fooRepository.findOne(1L,
new DynamicEntityGraph(Arrays.asList({"children", "pets"});