循环中不区分大小写的 isMember - JPA 条件 api
Case insensitive isMember in loop - JPA criteria api
我创建了以下谓词来匹配给定的字符串集,例如"a,b,c" 针对包含 @ElementCollection Set<String>
的列。
我想要所有包含 "a" 或 "b" 或 "c" 的条目。例如。所有这些 entries/set 匹配:
a
//因为一个
b,d
//因为 b
c,f,g
//因为c
我有一个有效的谓词 - 我只需要让它不区分大小写(不想更改数据库):
private Predicate matchStringSet(Set<String> set, SetAttribute<DeliveryModeEntity, String> attribute,
CriteriaBuilder criteriaBuilder, Root<DeliveryModeEntity> deliveryMode) {
List<Predicate> matchEach = new ArrayList<>();
for (String string : set) {
matchEach.add(criteriaBuilder.isMember(string.toLowerCase(), deliveryMode.get(attribute)));
}
return criteriaBuilder.or(matchEach.toArray(new Predicate[] {}));
}
如何使 deliveryMode.get(attribute)
使用小写或如何使这种大小写不敏感。
我尝试使用这里提到的连接:
但这在 for 循环中不起作用 - 它将为集合中的每个字符串创建一个连接。
我有一个类似的实体,Widget
,有标签:
@ElementCollection
@Column(name = "tag")
private List<String> tags = new ArrayList<>();
用你所拥有的,找到所有具有给定标签的小部件使用:
private Predicate matchTags(List<String> tags, Root<Widget> root, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<>();
for (String tag : tags) {
predicates.add(cb.isMember(tag, root.get(Widget_.tags)));
}
return PredicateReducer.OR.reduce(cb, predicates); // cb.or(predicates.toArray(new Predicate[0]));
}
要以不区分大小写的方式查找所有具有给定标签的Widget,首先加入标签然后执行类似搜索:
private Predicate matchTagsCaseInsensitive(List<String> tags, Root<Widget> root, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<>();
Join<Widget, String> joinedTag = root.join(Widget_.tags);
for (String tag : tags) {
predicates.add(cb.like(cb.lower(joinedTag), tag.toLowerCase()));
}
return PredicateReducer.OR.reduce(cb, predicates); // cb.or(predicates.toArray(new Predicate[0]));
}
编辑:添加 PredicateReducer
我发现自己经常 AND
-ing 或 OR
-ing 谓词,所以将这些操作包装到一个枚举中:
public enum PredicateReducer {
AND {
@Override
public Predicate reduce(CriteriaBuilder cb, List<Predicate> predicates) {
return cb.and(predicates.toArray(new Predicate[0]));
}
},
OR {
@Override
public Predicate reduce(CriteriaBuilder cb, List<Predicate> predicates) {
return cb.or(predicates.toArray(new Predicate[0]));
}
};
public abstract Predicate reduce(CriteriaBuilder cb, List<Predicate> predicates);
public Predicate reduce(CriteriaBuilder cb, Predicate... predicates) {
return reduce(cb, Arrays.asList(predicates));
}
}
我创建了以下谓词来匹配给定的字符串集,例如"a,b,c" 针对包含 @ElementCollection Set<String>
的列。
我想要所有包含 "a" 或 "b" 或 "c" 的条目。例如。所有这些 entries/set 匹配:
a
//因为一个b,d
//因为 bc,f,g
//因为c
我有一个有效的谓词 - 我只需要让它不区分大小写(不想更改数据库):
private Predicate matchStringSet(Set<String> set, SetAttribute<DeliveryModeEntity, String> attribute,
CriteriaBuilder criteriaBuilder, Root<DeliveryModeEntity> deliveryMode) {
List<Predicate> matchEach = new ArrayList<>();
for (String string : set) {
matchEach.add(criteriaBuilder.isMember(string.toLowerCase(), deliveryMode.get(attribute)));
}
return criteriaBuilder.or(matchEach.toArray(new Predicate[] {}));
}
如何使 deliveryMode.get(attribute)
使用小写或如何使这种大小写不敏感。
我尝试使用这里提到的连接:
但这在 for 循环中不起作用 - 它将为集合中的每个字符串创建一个连接。
我有一个类似的实体,Widget
,有标签:
@ElementCollection
@Column(name = "tag")
private List<String> tags = new ArrayList<>();
用你所拥有的,找到所有具有给定标签的小部件使用:
private Predicate matchTags(List<String> tags, Root<Widget> root, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<>();
for (String tag : tags) {
predicates.add(cb.isMember(tag, root.get(Widget_.tags)));
}
return PredicateReducer.OR.reduce(cb, predicates); // cb.or(predicates.toArray(new Predicate[0]));
}
要以不区分大小写的方式查找所有具有给定标签的Widget,首先加入标签然后执行类似搜索:
private Predicate matchTagsCaseInsensitive(List<String> tags, Root<Widget> root, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<>();
Join<Widget, String> joinedTag = root.join(Widget_.tags);
for (String tag : tags) {
predicates.add(cb.like(cb.lower(joinedTag), tag.toLowerCase()));
}
return PredicateReducer.OR.reduce(cb, predicates); // cb.or(predicates.toArray(new Predicate[0]));
}
编辑:添加 PredicateReducer
我发现自己经常 AND
-ing 或 OR
-ing 谓词,所以将这些操作包装到一个枚举中:
public enum PredicateReducer {
AND {
@Override
public Predicate reduce(CriteriaBuilder cb, List<Predicate> predicates) {
return cb.and(predicates.toArray(new Predicate[0]));
}
},
OR {
@Override
public Predicate reduce(CriteriaBuilder cb, List<Predicate> predicates) {
return cb.or(predicates.toArray(new Predicate[0]));
}
};
public abstract Predicate reduce(CriteriaBuilder cb, List<Predicate> predicates);
public Predicate reduce(CriteriaBuilder cb, Predicate... predicates) {
return reduce(cb, Arrays.asList(predicates));
}
}