【发布时间】:2014-10-10 19:44:12
【问题描述】:
我希望为结果提供内容过滤。我的(为简洁而编辑)实体如下所示:
节点:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Node {
@Id
@GeneratedValue
public Integer id;
}
场景:
@Entity
public class Scene extends Node {
@OneToMany(mappedBy = "scene", /*fetch = FetchType.EAGER, */cascade = CascadeType.ALL)
public List<Source> sources;
}
来源:
@Entity
public class Source extends Node {
@ManyToOne
public Scene scene;
@Enumerated(EnumType.ORDINAL)
public SourceType type;
}
以下是我希望实现的过滤器示例。
给定一个 SourceTypes 的集合,我希望选择所有场景,以便该场景由这些类型中的每一个的源引用。我使用带有以下谓词的 QueryDSL 来实现这一点:
private Predicate filterBySourceType(Collection<SourceType> it) {
BooleanBuilder bb = new BooleanBuilder();
for (SourceType st : it)
bb.and(QScene.scene.sources.any().type.eq(st));
return bb.getValue();
}
将一系列这些谓词组合起来以提供一个整体查询。仅选择一个 SourceType 时,结果查询如下所示:
Hibernate: select count(scene0_.id) as col_0_0_ from Scene scene0_ inner join Node scene0_1_ on scene0_.id=scene0_1_.id where exists (select 1 from Source source1_ inner join Node source1_1_ on source1_.id=source1_1_.id where (source1_.id in (select sources2_.id from Source sources2_ inner join Node sources2_1_ on sources2_.id=sources2_1_.id where scene0_.id=sources2_.scene_id)) and source1_.type=?)
我相信上面发生的事情是交叉连接,因此(2k 个场景,1k 个源)查询需要几秒钟。
我尝试切换到具体的类多态性来消除节点连接,但没有明显的性能提升。
如何优化该谓词?
【问题讨论】:
标签: hibernate jpa spring-data-jpa querydsl