2011-12-05 32 views
4

如何在JPA查詢中表示日期,而不使用(鍵入)參數?
如果日期是真正固定的(例如,1980年3月1日),代碼:JPA日期字面量

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嵌入到我的查詢中。

UPDATE: 我改性樣品日期1980年1月3日,1980年1月1日,因爲它被,不明確的。

回答

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'} 

應該做的工作(大括號和撇號爲必填項)。

+0

我得到以下異常:org.hibernate.QueryException:意外的字符: '{'[從db.MyEntity myent選擇myent其中myent.thedate = {d '2011-11-29'} ...這似乎關於使用花括號語法的可能性的相當嚴重的問題:-(:-) – AgostinoX

+0

你輸入的確切查詢是什麼? –

+0

這就是確切的查詢:select myent from db.MyEntity myent where myent.theDate = {d'1980-03-01'}。但情況甚至更糟:這是有效的:從db.MyEntity myent中選擇myent where myent.theDate ='1980-03-01'但是在這種情況下,03將被視爲日期而不是月份。 – AgostinoX

2

我對我的querys使用了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(); 
+0

你可以提供一個簡短的例子嗎? – AgostinoX

+0

根據你的添加了一個較短的例子 – jk2

1

我花了幾天時間在這周圍挖。看來問題的根源在於Hibernate生成的語法不包含對時態文字的支持。

JPA規範不包括顳文字支持,但並不需要持久性提供者從JPA語法JDBC驅動程序的本地語法翻譯。從JPA2規格4.6.1:

「的JDBC轉義語法可用於日期,時間和時間戳記文字的規範,例如:

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

此語法日期的便攜性,時間和時間戳文字取決於正在使用的JDBC驅動程序。持久性提供程序不需要從此語法轉換爲數據庫或驅動程序的本地語法。「

這將是很好,如果休眠確實提供了日期文字的支持,但似乎這樣做的實施是一個涉及多一點,我會懷疑。

至於我的需求而言缺乏這裏的功能是,你不能做一個select coalesce(somePath, someDateLiteral)查詢。你仍然可以做一個where somePath=someDate。只要他們是映射實體,你可以拋出任何你想要的where子句。