当前位置: 首页 > 知识库问答 >
问题:

QueryDSL生成交叉联接

戚阳
2023-03-14

我希望为结果提供内容过滤。我的(为简洁起见而编辑)实体如下所示:

节点:

@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:从存在scene0_.id=scene0_1_.id 的场景中 scene0_选择 count(scene0_ scene0_1_.id) 作为col_0_0_col_0_0_scene0_.id=scene0_1_.id 上(从 source1_.id=source1_1_.id 上的源source1_内部 sources2_1_连接节点source1_1_中选择 1(在 source1_.id 中选择 sources2_.id sources2_ sources2_.id=sources2_1_.id,其中 scene0_.id=sources2_.scene_id))和source1_.type=?)

我相信上面发生的是交叉连接,因此(2k场景、1k来源)查询需要多秒钟。

我尝试切换到具体的类多态性,以消除节点连接,但性能没有明显提高。

如何优化该谓词?

共有1个答案

岳枫
2023-03-14

事实证明,您可以使用 JPASubQuery 来获取集合表达式并写出查询,就像使用普通的旧 SQL 编写查询一样。

        bb.and(QScene.scene.in(
                new JPASubQuery()
                        .from(source)
                        .where(source.type.eq(st))
                        .list(source.scene)
        ));
 类似资料:
  • 我正在尝试转换QueryDSL (JPA,Hibernate provider,Oracle database)中的以下SQL查询: 我的java代码: 它编译得很好,但我得到了一个运行时异常 ORA-00904:“公司_”。“ID”:无效标识符 这是根据Hibernate日志输出生成的查询: 如果我在Oracle中手工运行这个查询,我会得到同样的错误。不明白company的两个无用连接(comp

  • 我将PostgreSQL 9.6与Hibernate 5.2.10一起使用,并且有3个实体: 当Entity1加入Entity2通过Entity3过滤时,我需要删除Entity1的所有出现,如下所示: PS:在数据库中,所有的表都有外键。

  • 我想根据ModelB中的用户从modelA中获取数据。但这并不是强制要求我在ModelB中为每一个记录都有记录。所以当我使用下面的代码来获取数据时,它返回0条记录。 当我调试时,我发现QueryDsl将交叉联接。有人能告诉我如何修复这个问题吗?querydsl有没有办法添加左联接而不是交叉联接?下面是我的两个模型。

  • 问题内容: 我正在使用Hibernate 3.6和MSSQL 2012。 执行此HQL时 我正在获取此SQL 请注意 交叉连接 和where子句中的 附加条件* 。 根据Hibernate docs https://docs.jboss.org/hibernate/core/3.5/reference/en/html/queryhql.html#queryhql- joins- forms 隐式连

  • 根据Hibernate文档https://docs.jboss.org/Hibernate/core/3.5/referen/html/queryhql.html#queryhql-joins-forms 隐式联接应生成为内部联接。 我注意到有一个打开的bug https://hibernate.atlassian.net/browse/hhh-7707可能提到了这个问题,但没有人回答,而且它已经

  • 问题内容: 我一直在尝试查找有关我的查询的问题。该查询实际上是由HQL的hibernate生成的,但是生成的SQL并没有达到我的期望。稍微修改SQL会产生正确的结果,但是我不确定为什么修改会有所不同。 原始查询(不返回任何行) 修改的查询-用逗号替换交叉联接(隐式交叉联接) 返回一行 我的理解可能是错误的,因为写作与Writing相同。所以我不明白为什么查询返回不同的结果。 与导致此问题的第一个查