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;
}
我有一个用例,我需要在值列表中搜索 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;
}