SINGLE_TABLE单表继承场景下如何使用QueryDSL查询指定子类并排序
QueryDSL 实现单表继承下A、B子类数据查询
前提条件
确保项目已正确配置QueryDSL注解处理器,已生成对应查询实体类QParent、QA、QB。
方案1:父类查询根+类型过滤(推荐,无需处理字段对齐)
直接以父类Parent作为查询根,通过QueryDSL提供的instanceOf方法自动映射判别器过滤逻辑,代码如下:
// 注入已配置完成的JPAQueryFactory @Autowired private JPAQueryFactory queryFactory; public List<Parent> queryAAndB() { QParent qParent = QParent.parent; return queryFactory.selectFrom(qParent) // 过滤类型为A或B的实体,底层自动转换为type in ('a','b')条件 .where(qParent.instanceOf(A.class).or(qParent.instanceOf(B.class))) .orderBy(qParent.createdAt.asc()) .fetch(); }
该方案默认返回父类定义的公共字段,如需获取子类独有属性请使用方案2
方案2:Union 联合子类查询(支持返回子类特有字段)
如果业务需要读取A、B子类各自定义的特有字段,可以通过union联合两个子类的查询结果再排序:
public List<Parent> queryAAndBWithSubField() { QA qA = QA.a; QB qB = QB.b; QParent qParent = QParent.parent; return queryFactory.selectFrom(qA) .union(queryFactory.selectFrom(qB)) .orderBy(qParent.createdAt.asc()) .fetch(); }
注意:Union要求两个查询的返回字段结构完全一致,若A、B的独有字段差异较大需要手动对齐返回字段
非QueryDSL替代方案
如果不使用QueryDSL,可通过以下两种方式实现:
- JPQL查询:使用JPQL内置的
TYPE函数判断实体类型// 父类Repository中定义查询方法 @Query("SELECT p FROM Parent p WHERE TYPE(p) IN (A, B) ORDER BY p.createdAt ASC") List<Parent> findAAndB(); - 原生SQL查询:直接操作单表的判别器字段过滤
@Query(value = "SELECT * FROM parent WHERE type IN ('a','b') ORDER BY created_at ASC", nativeQuery = true) List<Parent> findAAndBByNativeSql();
内容的提问来源于stack exchange,提问作者Roger
相关产品推荐
相关产品推荐

