使用 JPA CriteriaBuilder 構建動態查詢時,需將字符串數組 vals 中的每個值轉為 LIKE '%val%' 並用 OR 連接。直接在 builder.or() 中寫死參數不可行,需先收集 Predicate 列表再轉數組傳入。
// 無法動態傳入可變參數
predicates.add(builder.or(
builder.like(expression, "%" + vals[0] + "%"),
builder.like(expression, "%" + vals[1] + "%"),
// ... 只能寫死
));
String[] str = value.split(","); // 假設輸入 "王,李,張"
List<Predicate> predicateList = new ArrayList<>();
for (int i = 0; i < str.length; i++) {
predicateList.add(builder.like(expression, "%" + str[i] + "%"));
}
Predicate[] p = new Predicate[str.length];
predicateList.toArray(p); // 轉為數組
predicates.add(builder.or(p)); // builder.or(Predicate...) 接收數組
CriteriaBuilder.or(Predicate... restrictions) 是可變參數方法,底層接收數組。List<Predicate> 動態添加,最後 toArray() 轉數組傳入。WHERE name LIKE '%王%' OR name LIKE '%李%' OR name LIKE '%張%'public Predicate buildNameLikePredicate(CriteriaBuilder cb, Expression<String> expr, String csvValues) {
if (csvValues == null || csvValues.isEmpty()) {
return cb.conjunction(); // 1=1 無條件
}
String[] vals = csvValues.split(",");
List<Predicate> list = new ArrayList<>(vals.length);
for (String v : vals) {
list.add(cb.like(expr, "%" + v.trim() + "%"));
}
return cb.or(list.toArray(new Predicate[0]));
}
動態構建 OR 條件時,收集 Predicate 到列表,轉數組傳給 builder.or(),避免硬編碼參數個數。