0..n带偏移和限制的结果转换会产生不准确的结果

问题描述 投票:0回答:1

我已经搜索了正确的答案,但遗憾的是没有找到QueryDsl SQL模块的任何工作解决方案。我正在尝试使用自定义属性上的左连接来获取具有0..n关系的简单实体:

class Parent {
    private Long id;
    private String uuid;
    private Set<Child> children;
}

class Child {
    private Long id;
    private String uuidRef;
}

为了能够填充dto我正在改变结果如下:

queryFactory().from(qParent)
    .leftJoin(qChild).on(qParent.uuid.eq(qChild.uuidRef))
    .where(...)
    .transform(GroupBy.groupBy(qParent.id).list(parentQBean))

父行具有多个子关​​系。除非我为分页pupropses的查询添加额外的限制和偏移量,否则一切正常。那天我想要前20个结果,所以我要添加.offset(0).limit(20)。

在db中有2个父记录,每个记录有2个子行。在transformig / grouping之后,我只得到18行/对象。我知道这是由于SQL查询本身,因为它将左连接行作为单独的结果行返回并且转换在内存中完成,但我想知道是否可以以某种方式处理SQL模块。我不想使用JPA,因为这是一个相当小的项目,只有很少的表,JPA / Hibernate会有点过分。 SQL模块非常适合这个:)

使用QueryDsl SQL 4.2.1和PostgreSQL 11.2

java postgresql querydsl
1个回答
0
投票

我会说JPA也不会“正确地”处理这种情况,至少在尝试一次性取出父母及其子女时也是如此。正如您已经注意到的那样,问题是偏移和限制应用于结果,如果父项有多个子项,则连接可以导致更少的父项被加载(或者甚至只有一个父项只有一部分子项,如果有的话许多)。因此,您必须将偏移量和限制应用于表示每行父项的内容。

你可以试试这样的东西(我不知道QueryDsl所以我只会使用伪SQL):

select ... from parent p join children c on ...
   where p.id in ( select distinct id from parent order by whatever offset x limit y )

所以你要做的是确定子查询中20个父母的id,然后将这些父母和他们的孩子一起加载,这可能会导致超过20个结果行(如果2个父母有2个孩子,则为22个)其他18个最多只有1个)。

© www.soinside.com 2019 - 2024. All rights reserved.