JPA CriteriaBuilder:List Join with IN query on joined column

JPA CriteriaBuilder: ListJoin with IN query on joined cloumn

我有一个用例,我需要在值列表中搜索 table。以下是架构:

案例table

Case_Id

CASE_CIN table

Case_Id

CASE & CASE_CIN table 通过 Many to Many.

加入

我需要根据提供的 CIN 列表搜索案例。这是我要实现的 SQL:

select distinct c.* from case c left join case_cin cc on c.case_id = cc.case_id where cc.cin in ("cin1", "cin2", "cin3");

这就是我基于单个 CIN 设计过滤条件的方式:

public static Specification<CaseEntity> buildSpecification(CaseSearchRequestDto criteria, String userName) {
    return (root, query, cb) -> {
        List<Predicate> predicates = new ArrayList<>();
    
        if (!isEmpty(criteria.getAssociatePartyCins())) {
            predicates.add(buildAssociatePartyCinsFilterPredicate(root, cb, query, criteria.getAssociatePartyCins());
        }

        return cb.and(predicates.toArray(new Predicate[0]));
    };
}

private static Predicate buildAssociatePartyCinsFilterPredicate(Root<CaseEntity> root, CriteriaBuilder cb, CriteriaQuery query, List<String> cins) {
    Predicate filterPredicate = cb.disjunction();
    
    ListJoin<CaseEntity, String> cinsJoin = root.joinList(FIELD_CASE_CINS, LEFT);
    filterPredicate.getExpressions().add(startWithString(cinsJoin, cb, **cins.get(0)**); // need to change logic here.

    query.distinct(true);
    return filterPredicate;
}

我还希望对每个 CIN 进行精确匹配,而不是 startWithString

任何人都可以帮助修改代码以允许按多个值进行搜索吗?

事实证明比我想象的要简单得多。只需要将条件替换为cinsJoin.in(cins).

private static Predicate buildAssociatePartyCinsFilterPredicate(Root<CaseEntity> root, CriteriaBuilder cb, CriteriaQuery query, List<String> cins) {
    Predicate filterPredicate = cb.disjunction();
    
    ListJoin<CaseEntity, String> cinsJoin = root.joinList(FIELD_CASE_CINS, LEFT);
    filterPredicate.getExpressions().add(cinsJoin.in(cins));

    query.distinct(true);
    return filterPredicate;
}