JPA CriteriaQuery 比较时间戳忽略时间部分
JPA CriteriaQuery compare Timestamp ignore time portion
假设我在 Oracle DB 中有这样一个列:
SOMETHING_TS TIMESTAMP WITH TIME ZONE
而且我想使用 CriteriaQuery 按此列进行筛选。
我可以使用本机查询来实现:
SELECT *
FROM SOMETHING
WHERE TRUNC(SOMETHING_TS) = TO_DATE('2016-12-08','YYYY-MM-DD');
但是在Java我没有这样做,下面是我的示例代码:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<MyClass> cq = cb.createQuery(MyClass.class);
Date date = new Date();
predicates.add(cb.equal(cb.function("TRUNC", Date.class, myClass.get("somethingTs")), cb.function("TO_DATE", Date.class, cb.parameter(Date.class, "somethingTs"), cb.literal("YYYY-MM-DD"))));
Predicate[] predArray = new Predicate[predicates.size()];
predicates.toArray(predArray);
cq.where(predArray);
TypedQuery<MyClass> query = em.createQuery(cq);
query.setParameter("somethingDt", date);
看来我找到了答案:
predicates.add(cb.equal(cb.function("TRUNC", Date.class, myClass.get("somethingTs")), cb.function("TO_DATE", String.class, cb.parameter(String.class, "somethingTs"), cb.literal("YYYY-MM-DD"))));
然后我设置参数的时候,我会设置查询日期的String格式。
谢谢!
Javatar 的回答没有解决我的具体情况,但如果它对任何人有帮助,这对我有帮助。
private List<MyClass> selectMyClassByDate(Date date) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<MyClass> cq = cb.createQuery(MyClass.class);
Root<MyClass> myClass = cq.from(MyClass.class);
cq.select(myClass);
cq.where(cb.equal(cb.function("date", Date.class,
myClass.get(MyClass_.timestamp)), date));
final TypedQuery<MyClass> tq = em.createQuery(cq);
log.fine(
tq.unwrap(org.apache.openjpa.persistence.QueryImpl.class)
.getQueryString());
List<MyClass> myClassList = tq.getResultList();
return myClassList;
}
抱歉,这仅适用于 MYSQL
Javatar 的答案即使有效也不完美,因为 to_date returns 日期而不是字符串。使用参数也没有多大意义,最好使用文字。这是我的答案,对任何人都适用。
predicates.add(criteriaBuilder.lessThanOrEqualTo(criteriaBuilder.function("TRUNC", java.sql.Date.class, root.get("executionDateTime")),
criteriaBuilder.function("TO_DATE", java.sql.Date.class, criteriaBuilder.literal(request.getExecutionToDate().toString()),
criteriaBuilder.literal("yyyy-mm-dd"))));
假设我在 Oracle DB 中有这样一个列:
SOMETHING_TS TIMESTAMP WITH TIME ZONE
而且我想使用 CriteriaQuery 按此列进行筛选。
我可以使用本机查询来实现:
SELECT *
FROM SOMETHING
WHERE TRUNC(SOMETHING_TS) = TO_DATE('2016-12-08','YYYY-MM-DD');
但是在Java我没有这样做,下面是我的示例代码:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<MyClass> cq = cb.createQuery(MyClass.class);
Date date = new Date();
predicates.add(cb.equal(cb.function("TRUNC", Date.class, myClass.get("somethingTs")), cb.function("TO_DATE", Date.class, cb.parameter(Date.class, "somethingTs"), cb.literal("YYYY-MM-DD"))));
Predicate[] predArray = new Predicate[predicates.size()];
predicates.toArray(predArray);
cq.where(predArray);
TypedQuery<MyClass> query = em.createQuery(cq);
query.setParameter("somethingDt", date);
看来我找到了答案:
predicates.add(cb.equal(cb.function("TRUNC", Date.class, myClass.get("somethingTs")), cb.function("TO_DATE", String.class, cb.parameter(String.class, "somethingTs"), cb.literal("YYYY-MM-DD"))));
然后我设置参数的时候,我会设置查询日期的String格式。
谢谢!
Javatar 的回答没有解决我的具体情况,但如果它对任何人有帮助,这对我有帮助。
private List<MyClass> selectMyClassByDate(Date date) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<MyClass> cq = cb.createQuery(MyClass.class);
Root<MyClass> myClass = cq.from(MyClass.class);
cq.select(myClass);
cq.where(cb.equal(cb.function("date", Date.class,
myClass.get(MyClass_.timestamp)), date));
final TypedQuery<MyClass> tq = em.createQuery(cq);
log.fine(
tq.unwrap(org.apache.openjpa.persistence.QueryImpl.class)
.getQueryString());
List<MyClass> myClassList = tq.getResultList();
return myClassList;
}
抱歉,这仅适用于 MYSQL
Javatar 的答案即使有效也不完美,因为 to_date returns 日期而不是字符串。使用参数也没有多大意义,最好使用文字。这是我的答案,对任何人都适用。
predicates.add(criteriaBuilder.lessThanOrEqualTo(criteriaBuilder.function("TRUNC", java.sql.Date.class, root.get("executionDateTime")),
criteriaBuilder.function("TO_DATE", java.sql.Date.class, criteriaBuilder.literal(request.getExecutionToDate().toString()),
criteriaBuilder.literal("yyyy-mm-dd"))));