java - CriteriaBuilder:在运行时根据 DataType 创建 Criteria
问题描述
我有一个这样的简化Entity
类:
@Entity
public class Student {
String name;
Date birthday;
Integer term;
}
第三方依赖项 (DataTables) 以 a 的形式发送搜索请求,Map<String,String>
其中key
是实体属性的名称,而value
search 是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
or 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())
}
解决方案
这不是最好的方法,但您可以只使用类的简单名称:
String className= student.get(filter.getKey()).getClass().getSimpleName();
switch (className) {
case "Integer":
return cb.equal(student.get(filter.getKey()), filter.getValue())
case "String":
return cb.like(student.get(filter.getKey()), "%"+filter.getValue()+"%");
}
推荐阅读
- mysql - Insert into.....values((select statement), value1, value2, value3) Select 语句返回多列
- javascript - 我得到空数组有什么问题?
- php - PHP MySQLi 连接文件 - 错误/异常处理
- r - 如何在R中对面板数据进行二进制分类?
- ios - 如何让 iOS/macOS 在其 NetworkExtension 运行时更新我们的应用程序?
- c# - WPF 应用程序 (.NET Core) 对类库 (.NET Core) 的 clr 命名空间引用无法加载文件或程序集
- java - 如何在 Spring Boot 中重载 KafkaListener 方法
- c++ - 使用 C++ 的分支模拟器
- javascript - 每秒生成百分之一的宽度
- javascript - npm init 模板如何工作?