java – 按其元素的多个属性过滤集合 – QueryDSL
发布时间:2020-12-15 02:16:13 所属栏目:Java 来源:网络整理
导读:我正在研究基于QueryDSL的动态过滤器组件,并使用 SpringData进行查询执行.因此,我从收到的数据ad创建Predicate实例,并将其传递给QueryDslPredicateExecutor.对于对实体属性的动态访问,我使用键入实体类的通用PathBuilder. 考虑以下(简化)代码: class Offer
我正在研究基于QueryDSL的动态过滤器组件,并使用
SpringData进行查询执行.因此,我从收到的数据ad创建Predicate实例,并将其传递给QueryDslPredicateExecutor.对于对实体属性的动态访问,我使用键入实体类的通用PathBuilder.
考虑以下(简化)代码: class Offer { List<LanguageToName> names; } class LanguageToName { String name; String language; } 当我尝试查询Offer entites时,在其集合名称元素中具有属性’abc’,我只需创建谓词,如下所示: pathBuilder.getCollection("names",LanguageToName.class).any().getString("name") .like("%" + fieldData.getFieldValue() + "%"); 但是,我无法想出一个解决方案,使用PathBuilder通过包含对象的多个属性来过滤集合.当我使用.and()附加上面的代码并通过pathBuilder变量再次访问集合时,我自然会得到相当于使用AND EXISTS …附加sql查询的结果,这不是所需的结果.我也尝试使用getCollection().contains(),但是我无法创建Expression< LanguageToName>这将描述这种情况. 有没有办法创建一个谓词,它可以通过集合中元素的多个属性过滤实体,这是查询实体的一个字段? 解决方法
我在项目中遇到了同样的问题.
我的解决方法是手动构建exists子查询. 假设您的两个类都映射为实体: @Entity @Table(name = "Offer") public class Offer { @Id String id; @OneToMany(fetch = FetchType.LAZY,mappedBy = "offer") List<LanguageToName> names; } @Entity @Table(schema = "dcsdba",name = "Language_To_Name") public class LanguageToName { @Id String id; @ManyToOne(fetch= FetchType.LAZY) @JoinColumn(name="Offer_id") private Offer offer; String name; String language; } 使用any()进行简单查询: BooleanExpression namesFilter = QOffer.offer.names.any().name.eq("Esperanto"); 映射到 select offer0_.id as id1_7_ from offer offer0_ where exists ( select 1 from dcsdba.language_to_name names1_ where offer0_.id=names1_.offer_id and names1_.name=? ) 子查询: BooleanExpression namesFilter = JPAExpressions.selectOne() .from(languageToName) .where(languageToName.offer.eq(QOffer.offer) .and(languageToName.name.eq("Esperanto"))) .exists(); 地图到: select offer0_.id as id1_7_ from offer offer0_ where exists ( select 1 from dcsdba.language_to_name languageto1_ where languageto1_.offer_id=offer0_.id and languageto1_.name=? ) 它完全匹配以前的SQL. BooleanExpression namesFilter = JPAExpressions.selectOne() .from(languageToName) .where(languageToName.offer.eq(QOffer.offer) .and(languageToName.name.eq("Esperanto")) .and(languageToName.language.like("E%"))) .exists(); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |