首页 > 解决方案 > CriteriaBuilder:在运行时根据 DataType 创建 Criteria

问题描述

我有一个这样的简化Entity类:

@Entity
public class Student {
    String name;
    Date birthday;
    Integer term;
}

第三方依赖项 (DataTables) 以 a 的形式发送搜索请求,Map<String,String>其中key是实体属性的名称,而valuesearch 是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标准不适用于Integeror 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())
}

标签: javacriteria-apijpa-2.1

解决方案


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

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

推荐阅读