Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Java - L'API InMemorySQL
Pour manipuler des objets Java avec des requêtes SQL

Le , par Gugelhupf

0PARTAGES

L'API Stream en Java 8 ou l'API Linq en C# permettent de manipuler des collections d'objets en s'inspirant du langage SQL, mais ces concepts, bien que très puissants imitent le SQL sans forcément supporter l'ensemble de son potentiel.

Imaginez que vous ayez un ensemble de collection à manipuler : utiliser des fonctions d'agrégat (COUNT(), MIN(), MAX(), SUM(), AVG()), réaliser des jointures externes (LEFT/RIGHT/FULL) etc... Y arriverez-vous de manière aisée avec l'API Stream ou Linq ? Ne préféreriez-vous pas simplement réaliser cela à partir d'une simple requête SQL ?

L'API InMemorySQL a été créée afin de simplifier ce type de manipulation avancée, sans ré-inventer le SQL mais en le ré-utilisant, vos collections représentent tout simplement des tables (avec des alias t1, t2, tn etc) sur lesquels vous pourrez effectuer un ensemble d'opérations SQL puis en retirer une nouvelle collection d'objet.

Voici un exemple d'utilisation :
Code Java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import fr.ekinci.dbmsreplication.inmemorysql.InMemorySQL; 
//... 
  
String sqlRequest = "SELECT t1.id_d1 AS id_d1, t1.attr2 AS attr2, t1.attr3 AS attr3, t2.id_d2 AS id_d2, t2.attr4 AS attr4, t3.id_d3 AS id_d3, t3.attr5 AS attr5 " + 
    " FROM t1" + 
    " LEFT JOIN t2" + 
    " ON t1.id_d1 = t2.id_d1" + 
    " LEFT JOIN t3" + 
    " ON t2.id_d2 = t3.id_d3" + 
    " ORDER BY t1.id_d1, t2.id_d2, t3.id_d3"; 
  
List<Dumb1> ldb1 = new ArrayList<>();       // remplir 
Set<Dumb2> ldb2 = new HashSet<>();          // remplir 
Collection<Dumb3> ldb3 = new ArrayList<>(); // remplir 
  
List<ReturnDumb> result = new InMemorySQL() 
    .add(Dumb1.class, ldb1) // ldb1 aura pour alias t1 
    .add(Dumb2.class, ldb2) // ldb2 aura pour alias t2 
    .add(Dumb3.class, ldb3) // ldb3 aura pour alias t3 
    .executeQuery(ReturnDumb.class, sqlRequest);

N'hésitez pas à importer le projet grâce à Maven (ou autres outils de gestion de dépendances) :
Code XML : Sélectionner tout
1
2
3
4
5
<dependency> 
    <groupId>com.github.gokan-ekinci</groupId> 
    <artifactId>dbms-replication</artifactId> 
    <version>1.0</version> 
</dependency>


L'API InMemorySQL vous permet :
  • D'utiliser les fonctionnalités SQL standard de votre choix (COUNT(), MIN(), MAX(), SUM(), AVG(), INNER JOIN, LEFT/RIGHT JOIN etc). InMemorySQL utilise l'implémentation HSQLDB/HyperSQL.
  • D'utiliser des placeholders, la méthode executeQuery() possède la signature suivante : executeQuery(yourReturnType : Class, sqlQuery : String, placeholders : Object...)
  • D'utiliser des classes sans aucune contrainte particulière. Il n'y a pas de configuration, interface, annotation ou classe à utiliser sur les classes que vous manipulez.


En savoir plus :
  • Cette API utilise vos attributs (pas vos getters), l'API retrouve les attributs de votre instance ainsi que ceux des super classes dont votre instance hérite.
  • Vos collections/listes auront automatiquement pour alias t1, t2, tn, tn+1 (par ordre d'ajout).
  • Vos classes (les classes DumbN dans l'exemple du dessus) auront un minimum de contrainte :
    • Manipuler uniquement les champs de type primitif/Wrapper (sauf char/Character), et String.
    • Utiliser le type java.sql.Timestamp pour les champs de type date.
  • Votre type de retour (ReturnDumb dans l'exemple du dessus) possède quelques contraintes aussi :
    • Utilisez uniquement les Wrapper Java pour votre type de retour car les primitifs en Java ne supportent pas null.
    • Les champs VARCHAR et TEXT en SQL sont représentés par String en Java.
    • Les champs INT en SQL sont représentés par Integer en Java, n'utilisez pas le type Long ou BigInteger pour ce type de champ.
    • Les champs BIGINTEGER en SQL sont représentés par Long en Java, n'utilisez pas le type Integer ou BigInteger pour ce type de champ.
    • Les champs DECIMAL en SQL sont représentés par java.math.BigDecimal en Java, n'utilisez pas Double pour ce type de champ.
    • Les champs TIMESTAMP en SQL sont représentés par java.sql.Timestamp en Java, n'utilisez pas java.util.Date pour ce type de champ.
  • Concernant votre requête SQL :
    • Seuls les champs avec un alias seront récupérés dans votre résultat (ex: SELECT t1.monAttributQuiSeraRecupere AS monAttributQuiSeraRecupere, t1.attributQuiNeSeraPasRecupere FROM t1).
    • Vous êtes libre de créer des sous-requêtes, mais pas au niveau de votre premier SELECT (ne faite pas ceci : SELECT (SELECT t1.field FROM t1) AS field FROM t1).
    • N'utilisez pas de mot-clés réservés pour vos nom d'attribut, ou même essayer de les échapper avec un ` ou en les précédant d'un _ (ex: Group ou `Group` ou _group).



N'hésitez pas à donner votre avis
Projet Github : https://github.com/eau-de-la-seine/dbms-replication
Mon site : https://gokan-ekinci.appspot.com/

Une erreur dans cette actualité ? Signalez-le nous !