【发布时间】:2019-05-09 16:17:23
【问题描述】:
我正在使用 Spring Data JPA 并拥有映射到各自表的实体。我需要查询结果,以便我可以根据他们的strength 获取所有父母和每个父母一个孩子。
@Entity
public class Parent {
@Id
Long id;
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
private List<Child> children;
}
@Entity
public class Child {
@Id
Long id;
@Enumerated(EnumType.STRING)
private Strength strength;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "parent_id", nullable = false, insertable = true, updatable = false)
private Parent parent;
}
public Enum Strength {
STRONG,
NORMAL,
WEAK
}
我有一个基本的 crud 存储库,如下所示:
@Repository
public interface ParentRepository extends CrudRepository<Parent, Long>{}
一些规则和假设:
- 孩子属于单亲家庭
- 一个父对象在 DB 中可以有多个子对象
- 父母可以有 0 或 1 个力量 = STRONG 的孩子
- 父母将有 1 个力量 = 正常的孩子
- 父级将有 0 个或多个子对象的强度 = WEAK
- 软弱的孩子永远不会回来
- 下面的
getParentAndStrongChildren方法最多应返回 1 个子项。
我可以在 Spring 中对 Parent Repository 方法进行 findAll 查询,然后将结果映射到内存中,如下所示
public List<Parent> getParentAndStrongChildren(){
List<Parent> parents = parentRepository
.findAll().stream()
.map(p -> {
if(p.getChildren() != null && p.getChildren.size() > 1){
Child found = p.getChildren().stream()
.filter(c -> c.getStrength() == Strength.STRONG)
.findFirst()
.orElseGet(()-> p.getChildren().stream()
.filter(c -> c.getStrength() == Strength.NORMAL)
.findFirst()
.orElse(null));
p.setChildren(found == null ? null : new Arrays.asList(found));
}
}
return parents;
}
问:有没有什么办法不在内存中做过滤,而依靠JPQL和@Query注解来实现呢?
【问题讨论】:
-
你有很多逻辑,也许只有原生 SQL 才能为你完成这项工作。你能在 SQL 查询上做那个逻辑吗?我们将最容易帮助您使用 SQL 查询。
标签: java spring java-8 spring-data-jpa jpql