如何使用 JPA Criteria API 搜索字符串的日期字段

tec*_*rat 4 java mysql jpa

这是一个从我这里的另一个问题衍生出来的问题。我认为最好在有人(@Franck)指出这个链接这个链接之后提出一个不同的问题。

我对如何使用 JPA Criteria API 在数据库日期列(在我的例子中是 MySQL DATETIME)中搜索字符串感到困惑

这是我所做的;

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Client> cq = cb.createQuery(Client.class);
Root<Client> entity = cq.from(Client.class);
cq.select(entity);

List<Predicate> predicates = new ArrayList<Predicate>();
predicates.add(cb.like(cb.lower(entity.get("dateJoined").as(String.class)), "%"+search.toLowerCase()+"%")); 

cq.where(predicates.toArray(new Predicate[]{}));
TypedQuery<Client> query = em.createQuery(cq); //<--- Error gets thrown here
return query.getResultList();
Run Code Online (Sandbox Code Playgroud)

但它失败了,但有以下例外;

java.lang.IllegalArgumentException: Parameter value [%10-2015%] did not
match expected type [java.lang.Character]
Run Code Online (Sandbox Code Playgroud)

10-2015正在搜索的字符串在哪里;

我被困在如何实现这一目标上。我需要帮助。

tec*_*rat 7

好的,在对各种策略进行了大量试验之后,这就是我所做的最终奏效的事情。

我在这里看到这篇文章,突然想起了 JPATuple接口,它是一个可以返回多个结果类型的对象。所以要执行我的like比较,并且由于 Date 不能简单地转换为 String 这里是步骤;

  1. 我把这个列作为 Tuple
  2. 检查元组对象,看看它是否可以从 Date 分配
  3. 如果是,则获取日期格式表达式并将其传递给like表达式。

所以基本上,这就是我最初拥有的显然失败的东西;

predicates.add(cb.like(cb.lower(entity.get("dateJoined").as(String.class)), "%"+search.toLowerCase()+"%")); 
Run Code Online (Sandbox Code Playgroud)

现在,这就是我所拥有的,效果很好;

Path<Tuple> tuple = entity.<Tuple>get("dateJoined");
if(tuple.getJavaType().isAssignableFrom(Date.class)){
    Expression<String> dateStringExpr = cb.function("DATE_FORMAT", String.class, entity.get("dateJoined"), cb.literal("'%d/%m/%Y %r'"));
    predicates.add(cb.like(cb.lower(dateStringExpr), "%"+search.toLowerCase()+"%"));
}
Run Code Online (Sandbox Code Playgroud)

值得注意的注意事项-

  1. 我知道,无论从哪里开始搜索,我的所有日​​期都以这种形式显示,07/10/2015 10:25:09 PM因此我能够知道如何将like表达式中的比较日期格式化为"'%d/%m/%Y %r'".
  2. 这只是适用于日期的一步。大多数其他类型,例如 int、long、char ...等...都可以直接转换为字符串,随着我探索更多类型的数据,我肯定会对不能直接转换为字符串的任何其他类型执行相同的操作.

尽管这对我来说非常有效,但在我将其标记为正确答案之前,我将对其进行一些更广泛的测试,并在此过程中保持开放以供对我的策略有任何保留意见的任何人发表评论。

最后,对于这以任何方式帮助的那个人......干杯!