CriteriaBuilder:在运行时根据 DataType 创建 Criteria
Posted
技术标签:
【中文标题】CriteriaBuilder:在运行时根据 DataType 创建 Criteria【英文标题】:CriteriaBuilder: Create Criteria based on DataType at runtime 【发布时间】: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())
【问题讨论】:
【参考方案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 而不是通用值 <T>
@Thanthla 什么返回 pdat.get(filter.getKey())?对于字符串、整数和日期过滤器?
返回一个PathRoot<Student> student = cq.from(Student.class);
是 CriteriaBuilder 中的一个类。 student.get(...)
返回属性的路径。见:docs.oracle.com/javaee/6/api/javax/persistence/criteria/…以上是关于CriteriaBuilder:在运行时根据 DataType 创建 Criteria的主要内容,如果未能解决你的问题,请参考以下文章
如何告诉 JPA CriteriaBuilder 按返回的唯一数据列排序?
使用 CriteriaBuilder 的 JPA 计数(*)。如何使用 CriteriaBuilder 检索 count(*) 列