2009-12-04 14 views
8

Je suis sûr que quelqu'un de familier avec HQL (je suis moi-même un débutant) peut facilement répondre à cette question.Comment interroger une date dans HQL (Hibernate) avec Joda Time?

Dans mon application Grails, j'ai la classe de domaine suivante.

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

Dans ma requête HQL, je veux récupérer des livres dont la date de sortie est inclus dans la gamme date1 .. date2

Par exemple, j'ai essayé:

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

Mais je suis arrivé à l'exception ...caused by: org.springframework.orm.hibernate3.HibernateQueryException: unexpected token: Le jeton d'erreur pointe vers le format de date (par exemple 2009-11-27T21:57:18.010+01:00 ou Fri Nov 27 22:01:20 CET 2009)

J'ai également essayé de convertir date1 en classe Date sans succès

Alors, quel est le code HQL correct? Dois-je convertir en un format spécifique (lequel?) En utilisant la méthode patternForStyle ou y a-t-il un autre moyen plus propre de le faire?

Merci,

Fabien.

+0

Comment est-ce que org.joda.time.DateTime correspond à votre SQL? Est-ce directement sur le terrain? java.util.Date et java.util.Calendar peuvent être mappés directement à un champ de base de données. Pour ce que ça vaut, puisque DateTime est un objet agrégé, le plugin Grails utilise probablement sous les couvertures un type de mapping personnalisé (voir la section 5.3 de Java Persistence with Hibernate). – Alan

+0

Comme indiqué dans le commentaire du code, DateTime utilise le type de mappage personnalisé PersistentDateTime de la bibliothèque joda-time-hibernate – fabien7474

Répondre

7

Je ne suis pas expert Grails, mais en java que vous auriez normalement faire date1 et date2 paramètres de requête et les lient en tant que tels:

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

Je suis sûr que vous pouvez faire quelque chose de similaire dans Grails. Si ce n'est pas le cas, formatez vos dates en yyyyMMddhhmmss (sans espaces) et placez-les entre guillemets simples - de cette façon, Hibernate les traitera comme des constantes et MySQL les convertira implicitement en dates.

+0

Merci beaucoup! Après votre réponse, je suis entré dans le code source de Grails et j'ai trouvé ceci pour l'exécution de requêtes HQL: Account.executeQuery ("sélectionnez un numéro distinct de Account a où a.branch =: branch ", [branch: 'London']) J'ai donc fait la même chose pour mon scénario et cela a fonctionné Thx – fabien7474

5

J'ai souligné par ChssPly, vous devez déclarer date1 et date2 comme paramètres de requête (positionnel ou nommé), puis les lier. Ici, nous utiliserons les paramètres nommés. Les paramètres comme d'habitude de passer de requête nommé avec Grails est via un Map:

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

Vérification de la documentation executeQuery() pour les détails de la syntaxe des deux options.

+0

Bonjour Pascal Merci pour votre aide, j'ai fait exactement ce que vous avez écrit. – fabien7474

3

Vous pouvez également comparer les dates en utilisant le format de date ISO8601 par exemple:

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' 

Je l'ai testé cela en utilisant MySql comme l'arrière. N'oubliez pas d'envelopper les dates comme une chaîne.