JPA дата буквальный - PullRequest
       8

JPA дата буквальный

4 голосов
/ 05 декабря 2011

Как представить дату в запросе JPA без использования (типизированных) параметров?
Если дата действительно фиксирована (например, 1 марта 1980 г.), код:

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 был неоднозначным.

Ответы [ 3 ]

5 голосов
/ 05 декабря 2011

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

должно работать (требуются фигурные скобки и апострофы).

2 голосов
/ 30 октября 2013

Я провел пару дней, копаясь в этом.Кажется, корень проблемы в том, что сгенерированная грамматика Hibernate не включает поддержку временных литералов.

Спецификация JPA включает поддержку временных литералов, но не требует, чтобы поставщики персистентности переводили из синтаксиса JPA вродной синтаксис драйвера JDBC.Из JPA2 Spec 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. Поставщикам постоянства не требуется переводить этот синтаксис в собственный синтаксис базы данных или драйвера. "

Было бы неплохо, если быHibernate предоставил поддержку литералов даты, но кажется, что реализация этого немного сложнее, чем я подозревал.

Функциональность, которой здесь не хватает, насколько мне нужно, заключается в том, что вы не можете сделать select coalesce(somePath, someDateLiteral) запрос.Вы все еще можете сделать where somePath=someDate.Пока они сопоставлены, вы можете бросить все, что хотите, в предложении where.

2 голосов
/ 08 декабря 2011

Я использовал критерии Query для своих запросов, это просто замечательно.Это выглядит так:

@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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...