CriteriaBuilder:在运行时基于数据类型创建条件

时间:2019-01-25 13:51:30

标签: java criteria-api jpa-2.1

我有一个简化的CREATE TRIGGER name BEFORE INSERT, BEFORE UPDATE ON table... 类,如下所示:

Entity

第三方依赖项(DataTables)以@Entity public class Student { String name; Date birthday; Integer term; } 的形式发送搜索请求,其中Map<String,String>是实体属性的名称,而key是搜索{{1 }}。地图可能看起来像这样:

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如何扩展代码以基于属性数据类型定义条件?

我尝试过这个,不幸的是在Java中是不可能的:

Integer

1 个答案:

答案 0 :(得分:0)

这不是最好的方法,但是您可以仅使用类的简单名称:

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()+"%");
}