Exemples de requêtes de collections Java intégrées à la mémoire

Les exemples suivants expliquent comment implémenter les requêtes sur des collections intégrées à la mémoire dans pureQuery.

Exemple de requête simple sur une collection

Dans cet exemple, la collection est un objet java.util.List et est une implémentation de l'interface java.lang.Iterable. Si vous renvoyez une liste d'objets Customer matérialisée, vous pouvez poser plusieurs questions concernant ces données sans avoir à accéder à nouveau à la source de données connectée.

Supposez par exemple que vous souhaitiez savoir combien de clients se trouvent dans la zone de vente de la baie de San Francisco Bay. Votre code peut se présenter comme suit :

Connection con = DriverManager.getConnection(...);    1 

Data db = DataFactory.getData(con);                   2 

Data qocdata = DataFactory.getData();                 3 

List<Customer> customers = db.queryList(              4 
  "SELECT * from SALES.CUSTOMER", Customer.class);

db.close();                                           5 

int sanFranCode = ...                                 6 

Integer countCity = qocdata.queryFirst(                   7 
"SELECT COUNT(*) FROM ?1.com.company.Customer AS cr WHERE cr.storeRegion = ?2",
Integer.class, customers, sanFranCode );

qocdata.close();                                      8 

Le code exécute les étapes suivantes :

  1. Créer une connexion à la base de données.
  2. Créer une instance de l'implémentation de l'interface Data. Un objet de connexion étant transmis au constructeur, vous pouvez utiliser les méthodes dans l'implémentation afin d'exécuter SQL sur une base de données.
  3. Créer une autre implémentation de l'interface Data. Aucun objet de connexion n'étant transmis au constructeur, vous pouvez utiliser les méthodes dans cette implémentation uniquement pour les requêtes sur les collections.
  4. Lancer une requête sur la base de données pour tous les clients et renvoyer les enregistrements clients sous forme d'objets Customer dans les clients de la liste.
  5. Fermer la connexion à la base de données.
  6. Définir la valeur de la zone de vente de la baie de San Francisco.
  7. Lancer une requête sur les objets client de la liste et renvoyer un compte des clients se trouvant dans la zone de vente cible.
  8. Fermer et publier toutes les ressources utilisées par qocdata.

Au lieu de fermer qocdata, vous pouvez effectuer une analyse supplémentaire des clients comme indiqué dans l'exemple suivant.

Exemple de requête complexe sur une collection

Pour un rapport de gestion, supposez que vous avez besoin de connaître le nombre de villes distinctes situées dans la zone de vente de la baie de San Francisco et les cinq plus grandes villes (en termes de nombre d'adresses) de cette région. Après le feu vert du département gestion, une campagne de mailing cible les clients dans ces cilles.

Vous pouvez utiliser une seule requête sur une source de données connectée et un petit nombre de logiques d'application utilisant les méthodes annotées pour lancer trois requêtes sur les collections.

Vous avez d'abord besoin d'une classe de transfert, utilisée à la fois par l'application d'appel et par les méthodes annotées :

public class CitySize {
  public String city;
  public Integer size;
}

Comme vous ne pouvez pas utiliser les méthodes d'une classe d'implémentation pour les requêtes sur les collections et les requêtes sur les bases de données, vous devez créer deux interfaces distinctes.

L'interface CustomerQuery définit la méthode de requête sur la source de données. La méthode getCustomersInRegion() renvoie une liste d'objets client représentant les clients se trouvant dans une zone de vente définie.

import com.company.Customer; 
public interface CustomerQuery
 {
   @Select(sql=
    "SELECT custId, name, ... FROM Customer WHERE region=?1")
   List<Customer> getCustomersInRegion(int r);
 }

L'interface RegionReport définit les méthodes de requête sur l'objet collection.

import com.company.Customer;
import com.company.Campaign.CitySize;
public interface RegionReport
{
  @Select(sql="SELECT COUNT(DISTINCT city) FROM ?1")
  public Integer countCities (List<Customer> curRegion);

  @Select(sql=
     "SELECT city, COUNT(DISTINCT addressL1) AS size " +
     " FROM ?1 GROUP BY city ORDER BY size DESC")
  public CitySize[] getCitySize(List<Customer> curRegion);

  @Select(sql="SELECT cr.this FROM ?1 AS cr, ?2 AS t5 " +
            " WHERE cr.city = t5.city ")  
  List<Customer> getMailingList(List<Customer> curRegion,
                       CitySize[] topFive);
}
Les méthodes exécutent les fonctions suivantes :
public Integer countCities (List<Customer> curRegion)
A partir d'une liste de clients de la zone actuelle, comptez le nombre de villes dans lesquelles se trouvent les clients.
public CitySize[] getCitySize(List<Customer> curRegion)
A partir d'une liste de clients de la zone actuelle, déterminez la taille de chaque ville en fonction de son nombre d'adresses différentes et renvoyez un tableau d'objets CitySize classés par ordre décroissant de taille.
List<Customer> getMailingList(List<Customer> curRegion, CitySize[] topFive)
A partir d'une liste de clients de la zone actuelle, sélectionnez tous ceux dont la ville figure dans la liste de villes donnée. L'utilisation de "ceci" permet de lancer une requête sur l'objet réel, dans ce cas à partir de List<Customer> curRegion à sélectionner dans List<Customer> renvoyé par getMailingList. Une requête similaire sélectionnant "cr.*" permet généralement d'obtenir une copie de l'objet renvoyé sur lequel la requête a été lancée

Après avoir généré les classes d'implementation pour les interfaces, vous pouvez établir le rapport à la gestion et la liste de clients ciblés avec une logique d'application se présentant comme suit :

 Connection con = DriverManager.getConnection(...);    1 
 CustomerQuery cQuery = 
    DataFactory.getData( CustomerQuery.class, con );  2 

 RegionReport inMem =
    DataFactory.getData( RegionReport.class );                         3 

 int sanFranCode = ...;                                                4 

 List<Customer> customers = cQuery.getCustomersInRegion(sanFranCode);  5 

cQuery.close();                                                        6 

 Integer cityCount = inMem.countCities(customers);                         7 
 System.out.println (                                                  8 
   " There are " + cityCount + " cities in region " + sanFranCode );
 System.out.println (
   " The largest 5, and their number of addresses are: " );

 CitySize[] allCityList = inMem.getCitySize(customers);                9 
 CitySize[] topFive = new CitySize[5];                                 10 
 for (int i=0; i<5; i++)                                               11 
 {  topFive[i] = allCityList[i];
    System.out.println (
      "   " + topFive[i].city + "  " + topFive[i].size);
 }

 List<Customer> mailingCust =                                          12 
         inMem.getMailingList(customers, topFive);

inMem.close();                                                         13 

Le code exécute les étapes suivantes :

  1. Créer une connexion à la base de données.
  2. Créer une instance de l'implémentation de l'interface CustomerQuery. Un objet de connexion étant transmis au constructeur, vous pouvez utiliser les méthodes dans l'implémentation afin d'exécuter SQL sur une base de données.
  3. Créer une instance de l'implémentation de l'interface RegionReport. Aucun objet de connexion n'étant transmis au constructeur, vous pouvez utiliser les méthodes dans cette implémentation uniquement pour les requêtes sur les collections.
  4. Définir la valeur de la zone de vente de la baie de San Francisco.
  5. Remplir la liste de clients avec les objets client représentant les clients se trouvant dans la zone de vente cible.
  6. Fermer et publier toutes les ressources utilisées par cQuery.
  7. Obtenir un compte des différentes villes dans lesquelles se trouvent les clients.
  8. Imprimer la première partie du rapport.
  9. Obtenir un tableau d'objets CitySikze, un seul objet pour chaque ville dans laquelle se trouvent les clients.
  10. Créer un tableau de type CitySize pour répertorier les objets CitySize pour les cinq plus grandes villes.
  11. Imprimer le nom et la taille des cinq plus grandes villes.
  12. Obtenir une liste des clients se trouvant dans les cinq plus grandes villes.
  13. Fermer et publier toutes les ressources utilisées par inMem.

Il est important d'indiquer que si la gestion détermine que le mailing cible est trop petit ou trop important, il vous suffit d'apporter une petite modification à la taille allouée au tableau CitySize et à sa boucle pour ajouter ou supprimer les objets Customer de l'éventuelle liste mailingCust. La méthode getMailingList() ne dépend pas de la taille de son tableau d'entrées.


Commentaires