首页 > 解决方案 > QueryDsl - 根据嵌套数组内容排除结果

问题描述

我正在尝试使用 QueryDsl 获取所有不包含特定类别的帖子

我的模型定义为:

邮政

@QueryEntity
@Table(name = "posts")
public class PostEntity implements {
    @Id
    @Column(name = "id")
    private String id;

    @OneToMany
    @JoinTable(
            name = "post_categories",
            joinColumns = @JoinColumn(name = "post_id", referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(name = "category_id", referencedColumnName = "id")
    )
    private List<CategoryEntity> categories;
}

类别

@QueryEntity
@Table(name = "categories")
public class CategoryEntity {
    @Id
    @Column
    private String id;

}

(为简洁起见,省略了一些 Lombok 注释)

两者通过post_categories连接表关联,以使用类别标记帖子。

我尝试使用与此类似的查询来排除分类为news

var query = QPostEntity
                .postEntity
                .categories.any().id.notIn("news");

但是,这仍然会返回该类别中的帖子 - 我让它正常工作的唯一方法是在notIn声明中包含所有帖子类别。

问题:如何查询不包含特定类别的帖子?


更新#1

似乎上面的查询生成类似于

where exists(
    select 1 from post_categories where category_id not in ('news')
    ) 

其中还包括所有其他类别的帖子。我发现以下查询确实产生了正确的结果(在语句not之前移动):exists

where not exists(
    select 1 from post_categories where category_id in ('news')
    )

这可以通过将 querydsl 重写为:

.categories.any().id.in("news").not();

然而,这似乎非常令人困惑。有什么更好的方法吗?

标签: javaspring-bootjpaquerydsl

解决方案


我会尝试用子查询来解决这个问题。你可以试试下面的吗?

SubQueryExpression<String> subquery = JPAExpressions.select(QCategoryEntity.categoryEntity.id)
                .from(QCategoryEntity.categoryEntity)
                .where(CategoryEntity.categoryEntity.eq("news"));

        return new JPAQueryFactory(em)
                .select(QPostEntity.postEntity)
                .from(QPostEntity.postEntity)
                .innerJoin(QPostEntity.postEntity.categories)
                .where(QCategoryEntity.categoryEntity.id.notIn(subquery));

可能您没有使用JPAQueryFactory... 如果没有,您能否分享您实际执行查询的方式?


推荐阅读