【发布时间】:2019-01-25 13:51:30
【问题描述】:
我有一个简化的Entity 类,如下所示:
@Entity
public class Student {
String name;
Date birthday;
Integer term;
}
第三方依赖项(DataTables)以Map<String,String> 的形式发送搜索请求,其中key 是实体属性的名称,value 是搜索String。地图可能如下所示:
key | value
------------------
name | Alice
birthday | 2000
term | 3
我目前使用这个实现,它适用于String 属性,如name:
public List<Student> getStudents(Map<String,String> filters) throws Exception {
//get builder
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery();
Root<Student> student = cq.from(Student.class);
//validate if attribut exists
try {
for(String key : filters.keySet()) {
student.get(key); //check if path exists
}
} catch (IllegalStateException | IllegalArgumentException ex ) {
throw new Exception("Invalid filter parameters!");
}
// select
cq.select(student);
//where
Predicate wherePredicate = cb.and(); // init with true;
for (Entry<String,String> filter : filters.entrySet()) {
wherePredicate = cb.and(wherePredicate,
cb.like(student.get(filter.getKey()), "%"+filter.getValue()+"%"));
}
cq.where(wherePredicate);
return entityManager.createQuery(cq).getResultList();
}
当然,like 条件不适用于Integer 或Date。 如何扩展我的代码以根据属性数据类型定义标准?
我试过这个,不幸的是在 Java 中是不可能的:
switch (student.get(filter.getKey()).getClass()) {
case Path<String>.class:
return cb.like(student.get(filter.getKey()), "%"+filter.getValue()+"%");
case Path<Integer>.class:
return cb.equal(student.get(filter.getKey()), filter.getValue())
}
【问题讨论】:
标签: java criteria-api jpa-2.1