Dans la clause from, le mot-clef FROM est optionnel
Il ne peut y avoir qu'une seule entité nommée dans la clause from ; elle peut optionnellement avoir un alias. Si le nom de l'entité a un alias, alors n'importe quelle référence de propriété doit être qualifiée en ayant un alias ; si le nom de l'entité n'a pas d'alias, alors il est illégal pour n'importe quelle référence de propriété d'être qualifiée.
Aucune jointure (implicite ou explicite) ne peut être spécifiée dans une requête HQL. Les sous-requêtes peuvent être utilisées dans la clause where ; les sous-requêtes, elles-mêmes, peuvent contenir des jointures.
La clause where est aussi optionnelle.
Par exemple, pour exécuter un UPDATE
HQL, utilisez la méthode Query.executeUpdate()
(la méthode est données pour ceux qui sont familiers avec PreparedStatement.executeUpdate()
de JDBC) :
Pour exécuter un DELETE
HQL, utilisez la même méthode Query.executeUpdate()
:
La valeur du int
retourné par la méthode Query.executeUpdate()
indique le nombre d'entités affectées par l'opération. Considérez que cela peut ou pas corréler le nombre de lignes
affectés dans la base de données. Une opération HQL pourrait entraîner l'exécution de multiples expressions SQL réelles,
pour des classes filles mappées par jointure (NdT: join-subclass), par exemple. Le nombre retourné indique le nombre d'entités
réelles affectées par l'expression. Retour à l'exemple de la classe fille mappée par jointure, un effacement d'une des
classes filles peut réellement entraîner des suppressions pas seulement dans la table qui mappe la classe fille, mais aussi
dans la table "racine" et potentillement dans les tables des classes filles plus bas dans la hiérarchie d'héritage.
Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); String hqlUpdate = "update Customer c set c.name = :newName where c.name = :oldName"; // or String hqlUpdate = "update Customer set name = :newName where name = :oldName"; int updatedEntities = s.createQuery( hqlUpdate ) .setString( "newName", newName ) .setString( "oldName", oldName ) .executeUpdate(); tx.commit(); session.close();
La pseudo-syntaxe pour l'expression INSERT
est : INSERT INTO EntityName properties_list select_statement
. Quelques points sont à noter :
Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); String hqlVersionedUpdate = "update versioned Customer set name = :newName where name = :oldName"; int updatedEntities = s.createQuery( hqlUpdate ) .setString( "newName", newName ) .setString( "oldName", oldName ) .executeUpdate(); tx.commit(); session.close();
Seule la forme INSERT INTO ... SELECT ... est supportée ; pas la forme INSERT INTO ... VALUES ... .
La properties_list est analogue à la spécification de la colonne
The properties_list is analogous to the column speficiation
dans l'expression SQL INSERT
. Pour les entités impliquées dans un héritage mappé, seules les propriétés directement définies à ce niveau de classe
donné peuvent être utilisées dans properties_list. Les propriétés de la classe mère ne sont pas permises ; et les propriétés
des classes filles n'ont pas de sens. En d'autres mots, les expressions INSERT
par nature non polymorphiques.
Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); String hqlDelete = "delete Customer c where c.name = :oldName"; // or String hqlDelete = "delete Customer where name = :oldName"; int deletedEntities = s.createQuery( hqlDelete ) .setString( "oldName", oldName ) .executeUpdate(); tx.commit(); session.close();
select_statement peut être n'importe quelle requête de sélection HQl valide, avec l'avertissement que les types de retour
doivent correspondre aux types attendus par l'insertion. Actuellement, c'est vérifié durant la compilation de la requête
plutôt que la vérification soit reléguée à la base de données. Notez cependant que cela pourrait poser des problèmes
entre les Type
s d'Hibernate qui sont équivalents opposé à égaux. Cela pourrait poser des problèmes avec des disparités entre une propriété définie comme un org.hibernate.type.DateType
et une propriété définie comme un org.hibernate.type.TimestampType
, même si la base de données ne ferait pas de distinction ou ne serait pas capable de gérer la conversion.
Pour la propriéte id, l'expression d'insertion vous donne deux options. Vous pouvez soit spécifier explicitement la propriété
id dans properties_list (auquel cas sa valeur est extraite de l'expression de sélection correspondante), soit l'omettre de
properties_list (auquel cas une valeur générée est utilisée). Cette dernière option est seulement disponible en utilisant
le générateur d'identifiant qui opère dans la base de données ; tenter d'utiliser cette option avec n'importe quel type
de générateur "en mémoire" causera une exception durant l'analyse. Notez que pour les buts de cette discussion, les générateurs
"en base" sont considérés être org.hibernate.id.SequenceGenerator
(et ses classes filles) et n'importe quelles implémentations de org.hibernate.id.PostInsertIdentifierGenerator
. L'exception la plus notable ici est org.hibernate.id.TableHiLoGenerator
, qu ne peut pas être utilisée parce qu'il ne propose pas un moyen de d'exposer ses valeurs par un select.
Pour des propriétés mappées comme version
ou timestamp
, l'expression d'insertion vous donne deux options. Vous pouvez soit spécifier la propriété dans properties_list (auquel
cas sa valeur est extraite des expressions select correspondantes), soit l'omettre de properties_list (auquel cas la valeur de graine
(NdT : seed value) définie par le org.hibernate.type.VersionType
est utilisée).
Un exemple d'exécution d'une expression INSERT
HQL :
translator-credits
For the id property, the insert statement gives you two options. You can either explicitly specify the id property in the
properties_list (in which case its value is taken from the corresponding select expression) or omit it from the properties_list
(in which case a generated value is used). This later option is only available when using id generators that operate in the
database; attempting to use this option with any "in memory" type generators will cause an exception during parsing. Note
that for the purposes of this discussion, in-database generators are considered to be org.hibernate.id.SequenceGenerator
(and its subclasses) and any implementors of org.hibernate.id.PostInsertIdentifierGenerator
. The most notable exception here is org.hibernate.id.TableHiLoGenerator
, which cannot be used because it does not expose a selectable way to get its values.
For properties mapped as either version
or timestamp
, the insert statement gives you two options. You can either specify the property in the properties_list (in which case its
value is taken from the corresponding select expressions) or omit it from the properties_list (in which case the seed value
defined by the org.hibernate.type.VersionType
is used).
An example HQL INSERT
statement execution:
Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); String hqlInsert = "insert into DelinquentAccount (id, name) select c.id, c.name from Customer c where ..."; int createdEntities = s.createQuery( hqlInsert ) .executeUpdate(); tx.commit(); session.close();