Introduction aux requêtes JDO 2/2

Introduction aux requêtes JDO 2/2

1. Vue d'ensemble

Dans le précédent article de cette série, nous avons montré comment conserver des objets Java dans différents magasins de données. Pour plus de détails, veuillez vérifierGuide to Java Data Objects.

JDO prend en charge différents langages de requête afin de donner au développeur la possibilité d'utiliser le langage de requête qu'il connaît le mieux.

2. Langages de requête JDO

JDO prend en charge les langages de requête suivants:

  • JDOQL - un langage de requête utilisant la syntaxe Java

  • JDOQL typé - suit la syntaxe JDOQL mais fournit une API pour faciliter l'utilisation des requêtes.

  • SQL - utilisé uniquement pour le SGBDR.

  • JPQL - fourni par Datanucleus, mais ne fait pas partie des spécifications JDO.

3. API de requête

3.1. Créer une requête

Pour créer une requête, nous devons spécifier la langue ainsi qu'une requêteString:

Query query = pm.newQuery(
  "javax.jdo.query.SQL",
  "select * from product_item where price < 10");

Si nous ne spécifions pas la langue, la valeur par défaut est JDOQL:

Query query = pm.newQuery(
  "SELECT FROM com.example.jdo.query.ProductItem WHERE price < 10");

3.2. Créer une requête nommée

Nous pouvons également définir la requête et y faire référence par son nom enregistré.

Pour ce faire, nous créons d'abord une classeProductItem:

@PersistenceCapable
public class ProductItem {

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.INCREMENT)
    int id;
    String name;
    String status;
    String description;
    double price;

    //standard getters, setters & constructors
}

Ensuite, nous ajoutons une configuration de classe au fichierMETA-INF/package.jdo pour définir une requête et la nommer:


    
        
            
            
            
        
    

Nous avons défini une requête nommée «PriceBelow10″.

Nous pouvons l'utiliser dans notre code:

Query query = pm.newNamedQuery(
  ProductItem.class, "PriceBelow10");
List items = query.executeList();

3.3. Fermeture d'unQuery

Pour économiser des ressources, nous pouvons fermer des requêtes:

query.close();

De manière équivalente, nous pouvons fermer un jeu de résultats spécifique en le passant en paramètre à la méthodeclose():

query.close(ResultSet);

3.4. Compilation d'unQuery

Si nous voulons valider une requête, nous pouvons appeler la méthodecompile():

query.compile();

Si la requête n'est pas valide, la méthode lancera unJDOException.

4. JDOQL

JDOQL est un langage de requête basé sur un objet, conçu pour fournir la puissance du langage SQL et préserver les relations d'objet Java dans le modèle d'application.

Les requêtes JDOQL peuvent être définies sous la formesingle-String.

Avant d'approfondir, passons en revue quelques concepts de base:

4.1. Classe de candidat

La classe candidate dans JDOQL doit être une classe persistable. Nous utilisons le nom complet de la classe au lieu du nom de la table dans le langage SQL:

Query query = pm.newQuery("SELECT FROM com.example.jdo.query.ProductItem");
List r = query.executeList();

Comme nous pouvons le voir dans l'exemple ci-dessus, lecom.example.jdo.query.ProductItem est la classe candidate ici.

4.2. Filtre

Un filtre peut être écrit en Java mais doit être évalué à une valeur booléenne:

Query query = pm.newQuery("SELECT FROM com.example.jdo.query.ProductItem");
query.setFilter("status == 'SoldOut'");
List result = query.executeList();

4.3. Les méthodes

JDOQL ne prend pas en charge toutes les méthodes Java, mais différentes méthodes que nous pouvons appeler à partir de la requête et qui peuvent être utilisées dans une large gamme:

query.setFilter("this.name.startsWith('supported')");

Pour plus de détails sur les méthodes prises en charge, veuillez vérifier celink.

4.4. Paramètres

Nous pouvons transmettre des valeurs aux requêtes en tant que paramètres. Nous pouvons soit définir les paramètres explicitement ou implicitement.

Pour définir un paramètre explicitement:

Query query = pm.newQuery(
  "SELECT FROM com.example.jdo.query.ProductItem "
  + "WHERE price < threshold PARAMETERS double threshold");
List result = (List) query.execute(10);

Ceci peut également être réalisé en utilisant la méthodesetParameters:

Query query = pm.newQuery(
  "SELECT FROM com.example.jdo.query.ProductItem "
  + "WHERE price < :threshold");
query.setParameters("double threshold");
List result = (List) query.execute(10);

Nous pouvons le faire implicitement en ne définissant pas un type de paramètre:

Query query = pm.newQuery(
  "SELECT FROM com.example.jdo.query.ProductItem "
  + "WHERE price < :threshold");
List result = (List) query.execute(10);

5. Typé JDOQL

Pour utiliser JDOQLTypedQueryAPI, nous devons préparer l'environnement.

5.1. Maven Setup


    org.datanucleus
    datanucleus-jdo-query
    5.0.2

...

    
        maven-compiler-plugin
        
            1.8
            1.8
        
    

Les dernières versions de ces dépendances sontdatanucleus-jdo-query etmaven-compiler-plugin.

5.2. Activation du traitement des annotations

Pour Eclipse, nous pouvons suivre les étapes ci-dessous pour activer le traitement annoté:

  1. Accédez àJava Compiler et assurez-vous que le niveau de conformité du compilateur est égal ou supérieur à 1,8

  2. Accédez àJava Compiler → Annotation Processing et activez les paramètres spécifiques au projet et activez le traitement des annotations

  3. Accédez àJava Compiler → Annotation Processing → Factory Path, activez les paramètres spécifiques au projet, puis ajoutez les fichiers JAR suivants à la liste:javax.jdo.jar,datanucleus-jdo-query.jar

La préparation ci-dessus signifie que chaque fois que nous compilons des classes persistantes, le processeur d'annotation dans le datanucleus-jdo-query.jar générera une classe de requête pour chaque classe annotée par@PersistenceCapable.

Dans notre cas, le processeur génère une classeQProductItem. La classe générée a presque le même nom que la classe persistable, bien qu’elle soit précédée de Q.

5.3. Créer une requête typée JDOQL:

JDOQLTypedQuery tq = pm.newJDOQLTypedQuery(ProductItem.class);
QProductItem cand = QProductItem.candidate();
tq = tq.filter(cand.price.lt(10).and(cand.name.startsWith("pro")));
List results = tq.executeList();

Nous pouvons utiliser la classe de requête pour accéder aux champs candidats et utiliser ses méthodes Java disponibles.

6. SQL

JDO prend en charge le langage SQL dans le cas où nous utilisons un SGBDR.

Créons une requête SQL:

Query query = pm.newQuery("javax.jdo.query.SQL","select * from "
  + "product_item where price < ? and status = ?");
query.setClass(ProductItem.class);
query.setParameters(10,"InStock");
List results = query.executeList();

Nous avons utilisé lessetClass() pour la requête afin de récupérer les objetsProductItem lorsque nous exécutons la requête. Sinon, il récupère un typeObject.

7. JPQL

JDO DataNucleus fournit le langage JPQL.

Créons une requête à l'aide de JPQL:

Query query = pm.newQuery("JPQL","select i from "
  + "com.example.jdo.query.ProductItem i where i.price < 10"
  + " and i.status = 'InStock'");
List results = (List) query.execute();

Le nom d'entité ici estcom.example.jdo.query.ProductItem. Nous ne pouvons pas utiliser uniquement le nom de classe. C'est parce que JDO n'a pas de métadonnées pour définir un nom d'entité comme JPA. Nous avons défini unProductItemp, et après cela, nous pouvons utiliserp comme un alias pour faire référence auxProductItem.

Pour plus de détails sur la syntaxe JPQL, veuillez vérifier celink.

8. Conclusion

Dans cet article, nous avons présenté les différents langages de requête pris en charge par JDO. Nous avons montré comment enregistrer les requêtes nommées pour les réutiliser et expliqué les concepts JDOQL, ainsi que l'utilisation de SQL et JPQL avec JDO.

Les exemples de code dans l'article peuvent être trouvésover on GitHub.