加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

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();

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读