Developpez.com

Plus de 2 000 forums
et jusqu'à 5 000 nouveaux messages par jour

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

Le , par Gugelhupf, Modérateur
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<T>, 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/


Vous avez aimé cette actualité ? Alors partagez-la avec vos amis en cliquant sur les boutons ci-dessous :


 Poster un commentaire

Avatar de ddoumeche ddoumeche - Membre éprouvé https://www.developpez.com
le 06/06/2016 à 13:52
Cela a l'air très jeune, mais extrêmement innovant et puissant.

Pourquoi avoir eu besoin d'un tel projet dans une replication de base de données ?
Avatar de Gugelhupf Gugelhupf - Modérateur https://www.developpez.com
le 25/07/2016 à 12:41
Bonjour @ddoumeche,

Merci pour ton retour

J'ai créé cet API car ce dernier répond à des problèmatiques que je n'ai pas trouvé sur le marché :
  • Comment réaliser des aggrégats et des jointures sur des objets Java ? L'API Stream de Java 8 ne le permet pas de manière aisée.
  • Mon client me fournit une extraction de sa BDD relationnel au format CSV/Excel (ou autre), comment dénormaliser la donnée assez rapidement pour placer son contenu dans une base NoSQL ?
  • L'API peut être exploitée à d'autres fins aussi...

N'hésitez pas à me faire des retours pour que je puisse améliorer l'API
Offres d'emploi IT
Data scientist senior H/F
Safran - Ile de France - Magny-les-Hameaux (Saclay)
Architecte sécurité des systèmes d'information embarqués H/F
Safran - Ile de France - 100 rue de Paris 91300 MASSY
Ingénieur H/F
Safran - Ile de France - Moissy-Cramayel (77550)

Voir plus d'offres Voir la carte des offres IT
Contacter le responsable de la rubrique SGBD & SQL