JPA日期文字

时间:2011-12-05 13:34:39

标签: date jpa-2.0

如何在不使用(类型化)参数的情况下在JPA查询中表示日期?
如果日期确实是固定的(例如,1980年3月1日),则代码为:

TypedQuery<MyEntity> q = em.createQuery("select myent from db.MyEntity myent where myent.theDate=?1", db.MyEntity.class).setParameter(1, d);

设置:

  

日期d =新日期(80,Calendar.MARCH,1);

非常冗长,不是吗?我想将1980/1/3嵌入到我的查询中。

更新: 我将样本日期修改为1980/1/3,因为它原来是1980/1/1,不明确。

3 个答案:

答案 0 :(得分:5)

IIRC你可以在JPQL查询中使用日期文字,就像在JDBC中一样,所以像这样:

// d at the beginning means 'date'
{d 'yyyy-mm-dd'} i.e. {d '2009-11-05'}

// t at the beginning means 'time'
{t 'hh-mm-ss'} i.e. {t '12-45-52'}

// ts at the beginning means 'timestamp'; the part after dot is optional
{ts 'yyyy-mm-dd hh-mm-ss.f'} i.e. {ts '2009-11-05 12-45-52.325'}

应该做的工作(需要花括号和撇号)。

答案 1 :(得分:2)

我在我的查询中使用了criteriaQuery,它非常棒。它看起来像:

@Override
public List<Member> findAllByDimensionAtTime(Dimension selectedDimension,
        Date selectedDate) {
    CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
    CriteriaQuery<Member> criteriaQuery = criteriaBuilder
            .createQuery(Member.class);
    Root<Member> member = criteriaQuery.from(Member.class);
    criteriaQuery
            .select(member)
            .where(criteriaBuilder.lessThanOrEqualTo(
                    member.get(Member_.validFrom), selectedDate),
                    criteriaBuilder.greaterThanOrEqualTo(
                            member.get(Member_.validTo), selectedDate),
                    criteriaBuilder.equal(
                            member.get(Member_.myDimensionId),
                            selectedDimension.getId())).distinct(true);
    return em.createQuery(criteriaQuery).getResultList();

validFrom和validTo是日期字段!

编辑:更短的例子(根据你的):

   CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
    CriteriaQuery<MyEntity> criteriaQuery = criteriaBuilder
            .createQuery(MyEntity.class);
    Root<MyEntity> entity= criteriaQuery.from(MyEntity.class);
    criteriaQuery
            .select(member)
            .where(criteriaBuilder.equal(
                            entity.get(MyEntity_.theDate),
                            new Date(80, Calendar.MARCH, 1);)).distinct(true);
    return em.createQuery(criteriaQuery).getResultList();

答案 2 :(得分:2)

我花了几天时间来研究这个问题。似乎问题的根源是Hibernate生成的语法不包括对时态文字的支持。

JPA规范确实包含对时态文字的支持,但不要求持久性提供程序从JPA语法转换为JDBC驱动程序的本机语法。来自JPA2 Spec 4.6.1:

&#34; JDBC转义语法可用于指定日期,时间和时间戳文字。例如:

SELECT o
FROM Customer c JOIN c.orders o
WHERE c.name = 'Smith'
AND o.submissionDate < {d '2008-12-31'}

此语法对日期,时间和时间戳文字的可移植性取决于所使用的JDBC驱动程序。持久性提供程序不需要将此语法转换为数据库或驱动程序的本机语法。&#34;

如果Hibernate确实提供了对日期文字的支持,那将是很好的,但似乎我的怀疑实现了这一点。

就我的需求而言,此处缺少的功能是您无法进行select coalesce(somePath, someDateLiteral)查询。你仍然可以做where somePath=someDate。只要他们重新映射实体,你就可以在where子句中抛出你想要的东西。