【问题标题】:CriteriaBuilder: Create Criteria based on DataType at runtimeCriteriaBuilder:在运行时根据 DataType 创建 Criteria
【发布时间】: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 条件不适用于IntegerDate如何扩展我的代码以根据属性数据类型定义标准?

我试过这个,不幸的是在 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


    【解决方案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()+"%");
    }
    

    【讨论】:

    • getSimpleName() 返回 SingularAttributePath 而不是通用值 &lt;T&gt;
    • @Thanthla 什么返回 pdat.get(filter.getKey())?对于字符串、整数和日期过滤器?
    • 返回一个Path类型的Object,其中T是学生属性的数据类型。
    • @Thanthla 能否请您发送方法 student.get() 的实现?这个方法在别的地方用过吗?
    • Root&lt;Student&gt; student = cq.from(Student.class); 是 CriteriaBuilder 中的一个类。 student.get(...) 返回属性的路径。见:docs.oracle.com/javaee/6/api/javax/persistence/criteria/…
    猜你喜欢
    • 1970-01-01
    • 2013-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-22
    • 1970-01-01
    • 1970-01-01
    • 2013-12-11
    相关资源
    最近更新 更多