2009-12-04 3 views
8

저는 HQL에 익숙한 사람 (저도 초보자입니다)이이 질문에 쉽게 답할 수 있다고 확신합니다.Joda Time을 사용하여 HQL (Hibernate)에서 날짜를 쿼리하는 방법은 무엇입니까?

내 Grails 애플리케이션에 다음 도메인 클래스가 있습니다. 내 HQL 질의에서

class Book { 
    org.joda.time.DateTime releaseDate //I use the PersistentDateTime for persisting via Hibernate (that use a DATETIME type for MySQL DB) 
} 

, 나는 date2

.. 그 릴리스 날짜 범위 date1에 포함되어있는 책을 검색 할 예를 들어 나는 시도 :

DateTime date1, date2 
... 
def queryStr = "select * from Book as b where b.releaseDate > $date1 and b.releaseDate < $date2" 
def res = Book.executeQuery(queryStr) 

하지만 예외를 가지고 ...caused by: org.springframework.orm.hibernate3.HibernateQueryException: unexpected token: 오류 토큰은 날짜 형식을 나타냅니다 (예 : 2009-11-27T21:57:18.010+01:00 또는 Fri Nov 27 22:01:20 CET 2009)

date1을 Date 클래스로 변환하지 못했습니다.

올바른 HQL 코드는 무엇입니까? patternForStyle 메서드를 사용하여 특정 형식 (어떤 형식으로 변환해야합니까?)을 수행해야합니까? 아니면 다른 방법으로이를 수행 할 수 있습니까?

감사합니다.

Fabien.

+0

org.joda.time.DateTime이 SQL에 어떻게 매핑됩니까? 직접 현장에 있습니까? java.util.Date와 java.util.Calendar는 데이터베이스 필드에 직접 매핑 할 수 있습니다. 가치있는 일로, DateTime은 집합 객체이기 때문에, Grails 플러그인은 아마도 커버 아래에 커스텀 매핑 타입을 사용할 것입니다 (Java Persistence with Hibernate의 sec 5.3 참조). – Alan

+0

코드 주석에서 언급했듯이 DateTime은 joda-time-hibernate 라이브러리의 PersistentDateTime 사용자 정의 매핑 유형을 사용 중입니다. – fabien7474

답변

7

나는 더 Grails의 전문가는 아니지만, 자바는 일반적으로 date1date2 쿼리 매개 변수를 만들어 주겠다고와 같은 바인드 :

String hql = "select * from Book as b where b.releaseDate > :date1 and b.releaseDate < :date2"; 
session.createQuery(hql).setDate("date1", date1).setDate("date2", date2).list(); 

난 당신이 Grails에 비슷한 일을 할 수 있는지입니다. 그렇지 않다면, 날짜를 yyyyMMddhhmmss (공백없이)으로 묶고 작은 따옴표로 묶으십시오. Hibernate는 그것들을 상수로 처리하고 MySQL은 암시 적으로 날짜로 변환합니다.

+0

감사합니다. 당신의 대답 뒤에, 나는 grails 소스 코드에 들어가서 HQL 쿼리를 실행하기 위해 이것을 찾았다. Account.executeQuery ("Account와 a.number를 선택하십시오. 내 시나리오에서 똑같이 했으므로 효과가있었습니다 .. – fabien7474

5

내가 ChssPly에서 지적한 바에 따르면 date1date2을 쿼리 매개 변수 (위치 또는 이름)로 선언하고 바인딩해야합니다. 여기서는 명명 된 매개 변수를 사용합니다. Grails가와라는 이름의 쿼리 매개 변수를 전달하는 가장 일반적인 방법은 Map 경유 :

def queryStr = "from Book b where b.releaseDate > :date1 and b.releaseDate < :date2" 
Book.executeQuery(queryStr, [date1: date1, date2: date2]) 

확인 두 옵션의 구문 자세한 내용은 executeQuery() 문서.

+0

안녕하세요, 파스칼 도와 주셔서 감사합니다. – fabien7474

3

또한 예컨대 ISO8601 날짜 형식을 사용하여 날짜를 비교할 수 있습니다

select * from Book as b 
where b.releaseDate > '2009-11-27T21:57:18.010+01:00' 
and b.releaseDate < '2010-11-27T21:57:18.010+01:00' 

나는 백 엔드로 사용하여이 MySQL을 테스트했습니다. 날짜를 문자열로 감싸는 것을 잊지 마십시오.

관련 문제