Affichage des articles dont le libellé est JDBC. Afficher tous les articles
Affichage des articles dont le libellé est JDBC. Afficher tous les articles

lundi 3 novembre 2014

H2 : la base de données "de poche" au service des développeurs

H2 est une base de données relationnelle écrite en Java qui s'avère très utile pour les développeurs.

Cette base de données ultra-légère n'est pas conçue pour supporter de gros volumes de données ni un nombre important d'utilisateurs, mais elle est extrêmement pratique pour les développeurs Java qui ont besoin de tester des applications ou des composants nécessitants des requêtes SQL via JDBC.

H2 présente de nombreux avantages :

  • légèreté : elle tient dans un fichier "zip" de 7 mo (y compris les sources et la documentation) 
  • portabilité : elle est constituée d'un seul fichier "jar" qui peut être exécuté sur tout système d'exploitation disposant de Java
  • fonctionnalités :  H2 dispose des mêmes possibilités que les "grandes bases de données" (schémas multiples, contrôle d'intégrité référentielle, triggers, fonctions, procédures stockés, colonnes auto-incrémentées, séquences, etc)
  • différents modes de fonctionnement : client/serveur ou embarqué

Pour installer H2 :
  1. Télécharger le fichier "Platform-Independent.zip" ( exemple : "h2-2014-08-06.zip" ) à partir du site http://www.h2database.com/ 
  2. Décompresser le fichier "zip"
  3. Pour démarrer la base : dans "bin" lancer "start.sh" ou "start.bat" selon le système d'exploitation
  4. Et voilà, la base est prête à accepter des connexions, une IHM web est même lancée dans le navigateur

Emplacement de stockage des données 

H2 permet de stocker les données d'une base soit en mémoire (très utile pour des données temporaires par exemple pour des tests JUnit), soit sur disque.
L'emplacement est déterminé lors de la connexion par la dernière partie de l'URL JDBC 


Les différents modes de fonctionnement

1) Le mode "embarqué" ( "embedded" in english )
Dans ce mode le moteur H2 fonctionne dans la même JVM que l'application qui l'utilise. La "connexion" est donc réduite à sa plus simple expression puisqu'elle n'utilise pas le réseau. Le principal avantage de ce mode est qu'il n'est pas nécessaire de démarrer la base (en tant qu'application autonome) avant de s'y connecter, ce qui est extrêmement pratique pour des tests JUnit par exemple.



2) Le mode "client/serveur" ou "connexion à distance" (  "remote" ) 
Dans ce mode la base de données est lancée en tant qu'application de type "serveur" et elle va accepter des connexions de "clients" distants (comme une base de données Oracle, PostgreSQL, etc)




3) Le mode "mixte"
Il s'agit d'un mode dans lequel le moteur de la base de données est "embarqué" dans une application spécifique qui peut l'utiliser et le piloter (notamment le démarrer). Une fois lancé le moteur H2 peut être utilisé avec des connexions locales et/ou distantes.



Les différents types d'URL de connexion 
Avec H2 l'URL JDBC est fondamentale puisqu'elle indique dans quel mode on souhaite se connecter à la base ( "remote" ou "embedded") et l'emplacement ou sont stockées les données de la base (en mémoire ou sur disque dans un répertoire du filesystem).
Voici donc un tableau qui représente les différents cas possibles :


Configuration JDBC "out of the box" 
jdbc.driverClassName=org.h2.Driver ( la classe du driver JDBC est dans le jar "h2-version.jar" )
jdbc.url=jdbc:h2:mem:mydb 
jdbc.username=sa
jdbc.password=sa

Le petit plus : initialisation par un script SQL à la connexion 
Pour ça il suffit d'utiliser  INIT=RUNSCRIPT FROM 'file_name'
Exemples d'URL :

  • jdbc:h2:mem:mydb;INIT=RUNSCRIPT FROM '~/init_mydb.sql'
    pour un script situé dans le répertoire du "user"
  • jdbc:h2:mem:mydb;INIT=RUNSCRIPT FROM 'classpath:sql/init_mydb.sql' 
    pour un script chargé via le "classpath" (par exemple situé dans "/src/main/resources" )

Dans bien des cas ça remplace efficacement DBUnit pour les tests..

Pour plus d'informations, voir le site de référence ; http://www.h2database.com/ 

mercredi 3 octobre 2012

JPA - Tracer les requêtes SQL avec Log4jdbc


L’utilisation de frameworks de persistance tels qu’ Hibernate, EclipseLink, TopLink ou OpenJPA permet de masquer toute la plomberie SQL et JDBC. Au point qu’on en oublierait presque qu’on travaille avec une base de données relationnelle.

Mais il y a toujours un moment où la réalité nous rattrape et où il devient indispensable de comprendre ce qui se passe de l’autre côté du décor. C'est à ce moment que le développeur s’interroge :  que fait concrètement notre framework de persistance ? Qu’est-ce qu’il nous cache ?

Bref, quelles sont les requêtes SQL envoyées à la base de données et à quel moment sont elles envoyées ?

Une première solution consiste à activer les traces du framework lui-même.

Par exemple avec JPA au niveau du fichier « persistence.xml » il suffit d’ajouter quelques propriétés de configuration.

Exemple pour  Hibernate :


Exemple pour EclipseLink :

Mais avec ce principe nous n’obtiendrons que ce que chaque framework veut bien nous donner. La configuration est propre à chaque environnement et le format des traces ne correspond pas forcément à ce que l’on souhaiterait.
Il s’agit donc d’une première réponse à la problématique des traces SQL, mais qui dans la plupart des cas se révélera insuffisante.

Ce serait tellement plus simple si on pouvait se situer entre le framework et la base de données pour voir passer les requêtes …  Et c’est là que les outils du type « proxy de driver JDBC » vont nous aider.

Avec un nom pareil on se doute bien du principe de fonctionnement …

Sans « proxy »


Avec « proxy »

Donc, on va « brancher » notre ORM sur un driver JDBC qui n’en est pas vraiment un. Cet usurpateur va être sollicité pour traiter les requêtes SQL qu’il va tracer, puis déléguer au « vrai » driver JDBC.

Il s’agit donc d’un « passe-plats » traceur.

Il existe différents outils de ce type, le plus connu étant certainement « P6Spy », célèbre espion au service de nos applications mais qui, contrairement à James Bond, a un peu vieilli (pas d’évolutions depuis plusieurs années).

Voici une liste (non exhaustive) de ce type d’outil :

Voyons maintenant comment utiliser Log4JDBC…

Pourquoi lui ? Parce qu’il est à jour (JDBC 4, JDK 1.6 et 1.7) et simple à installer (et pour P6Spy il y a déjà pas mal de doc en français sur la toile).

Architecture de Log4JDBC :






Log4JDBC permet d’utiliser différents types de loggers. Pour ce faire il s’appuie sur SLF4J : « Simple Logging Facade for Java » (http://www.slf4j.org/) une couche d’abstraction qui permet de s’isoler du logger concret qui sera utilisé (Log4J, java.util.logging, logback, etc… )
Dans le cas présent nous utiliserons Log4J (les classiques ça a du bon)

1) Récupérer les JAR nécessaires
  • SLF4J  ( 2 jars :  slf4j-api-x.x.x.jar  et  slf4j-log4j12-x.x.x.jar )
    http://www.slf4j.org/ :  Download  ( version 1.5 ou plus => prendre la dernière version )
On doit finalement avoir  4 JARs :




Il n’a plus qu’à ajouter ces JARs au projet, par exemple sous la forme d’une User Library sous Eclipse.

2) Insérer le « proxy » entre l’ORM et le « vrai driver JDBC »

2.1 ) Brancher Log4JDBC sur le « vrai driver JDBC »

Par défaut Log4JDBC cherche à utiliser les classes des drivers JDBC les plus courants

  • oracle.jdbc.OracleDriver ou oracle.jdbc.driver.OracleDriver pour Oracle
  • com.mysql.jdbc.Driver pour MySQL
  • org.postgresql.Driver pour PostgreSQL
  • etc…
Il connait une quinzaine de drivers classiques (voir la liste complète sur http://code.google.com/p/log4jdbc/ ). Pour ceux-là il n’y a donc aucune configuration à réaliser (il va trouver tout seul la classe du driver).

Si le driver JDBC n’est pas connu, il suffit de l’indiquer avec une « system property » :
     -Dlog4jdbc.drivers=<driverclass>[,<driverclass>...]

2.2 ) Brancher l’ORM sur le « faux driver » (Log4JDBC )

La classe qui simule de driver JDBC est « net.sf.log4jdbc.DriverSpy »
Il suffit donc de l’utiliser dans la configuration de l’ORM
Exemple dans « persistence.xml »



3) Configurer les loggers

Log4JDBC dispose de 5 loggers qui pourront être activés ou non en fonction des besoins :
  • jdbc.sqlonly    : trace uniquement le  SQL
  • jdbc.sqltiming  : trace le SQL et les statistiques de temps (durée d’exécution d’une requête SQL)
  • jdbc.audit      : trace tous les appels JDBC sauf pour les ResultSets
  • jdbc.resultset  : trace tous les appels aux objets ResultSet
  • jdbc.connection : trace les événements sur les connexions (open/close) et le nombre de connections ouvertes (utile pour identifier les « fuites » de connexions).
Il suffit de configurer au moins l’un de ces loggers dans le fichier « log4j.xml » pour voir les premières traces SQL.
Les loggers sont activés s’ils ont un des niveaux de trace  ERRORINFO  ou  DEBUG

Exemple de configuration Log4J :




4) Tester

Exemple de trace avec Hibernate :


Exemple de trace avec EclipseLink :


La configuration Log4J permet ensuite d’adapter le logger aux besoins (formatage des traces, nouveaux « appenders », etc… )