2009-12-04 20 views
8

Sono sicuro che qualcuno che abbia familiarità con HQL (io stesso sono un principiante) può facilmente rispondere a questa domanda.Come interrogare una data in HQL (Hibernate) con Joda Time?

Nella mia applicazione Grails, ho la seguente classe di dominio.

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

Nella mia interrogazione HQL, voglio recuperare i libri la cui data di uscita è incluso nella gamma date1 .. date2

Per esempio ho provato:

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

Ma ho avuto l'eccezione ...caused by: org.springframework.orm.hibernate3.HibernateQueryException: unexpected token: Il token di errore indica il formato della data (ad esempio 2009-11-27T21:57:18.010+01:00 o Fri Nov 27 22:01:20 CET 2009)

Ho anche provato a convertire date1 in una classe Date senza successo

Quindi qual è il codice HQL corretto? Devo convertire in un formato specifico (quale?) Usando il metodo patternForStyle o c'è un altro modo -cleaner- per farlo?

Grazie,

Fabien.

+0

Come funziona org.joda.time.DateTime al tuo SQL? È direttamente sul campo? java.util.Date e java.util.Calendar possono mappare direttamente a un campo di database. Per quello che vale, dato che DateTime è un oggetto aggregato, il plugin di Grails probabilmente usa sotto le copertine un tipo di mappatura personalizzato (vedi il paragrafo 5.3 di Java Persistence con Hibernate). – Alan

+0

Come indicato nel commento del codice, DateTime utilizza il tipo di mapping personalizzato PersistentDateTime dalla libreria joda-time-hibernate – fabien7474

risposta

7

Non sono un esperto Grails, ma in Java che normalmente si fanno date1 e date2 parametri di query e legatela in quanto tale:

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(); 

Sono sicuro che si può fare qualcosa di simile in Grails. In caso contrario, formattare le date come yyyyMMddhhmmss (senza spazi) e racchiuderle tra virgolette singole: in questo modo Hibernate le considererebbe come costanti e MySQL le convertirà implicitamente in date.

+0

Grazie mille !! Dopo la tua risposta, sono entrato nel codice sorgente di Grails e ho trovato questo per l'esecuzione di query HQL: Account.executeQuery ("seleziona un numero distinto da Account a dove a.branch =: branch ", [branch: 'London']) Quindi ho fatto lo stesso per il mio scenario e ha funzionato Thx. – fabien7474

5

Ho fatto notare da ChssPly, dovresti dichiarare date1 e date2 come parametri di query (posizionali o denominati) e quindi associarli. Qui, useremo i parametri denominati. Il solito modo per passare parametri di query denominati con Grails è tramite un Map:

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

Controllare executeQuery() documentazione per i dettagli sintassi di entrambe le opzioni.

+0

Ciao Pascal Thx per il tuo aiuto Ho fatto esattamente quello che hai scritto. – fabien7474

3

È anche possibile confrontare le date utilizzando il formato della data ISO8601 per esempio:

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' 

Ho provato questo utilizzando MySql come back-end. Ricorda solo di avvolgere le date come una stringa.

Problemi correlati