Licence CC BY-NC-SA

Introduction à MySQL et JDBC

Ce contenu est obsolète. Il peut contenir des informations intéressantes mais soyez prudent avec celles-ci.

Ce chapitre d'introduction est une entrée en matière qui a pour objectif de vous présenter rapidement les raisons d'être et les composants d'une base de données, vous guider dans son installation et vous expliquer comment une application Java communique avec elle.

Là encore, nous allons survoler un sujet extrêmement vaste et il faudrait un cours complet pour traiter proprement le sujet. Sur OpenClassrooms, Taguan a justement rédigé un excellent tutoriel de prise en main de la technologie que nous allons utiliser, que je vous encourage bien évidemment à lire avant de suivre ce chapitre : Administrez vos bases de données avec MySQL.

Présentation des bases de données

Une base de données… pourquoi ?

Vous connaissez déjà plusieurs moyens de stocker des informations depuis votre application :

  • dans des objets et leurs attributs, mais ceux-ci ne restent en mémoire que de manière temporaire, cette durée étant déterminée par leur portée. Au final, lorsque le serveur d'applications est arrêté, toutes les données sont perdues ;
  • dans des fichiers, dans lesquels vous savez écrire en manipulant les flux d'entrée et sortie. Les données ainsi écrites sur le disque ont le mérite d'être sauvegardées de manière permanente, et sont accessibles peu importe que l'application soit en ligne ou non. Le souci et vous le savez, c'est que cela devient vite très compliqué dès que vous avez beaucoup de données à enregistrer et à gérer.

Dans une application web, vous ne pouvez pas y couper, vous devez gérer une grande quantité de données : pour un site comme le Site du Zéro, il faut par exemple enregistrer et gérer les informations concernant les membres, les articles et tutoriels écrits dans les sections news et cours, les sujets et réponses écrits dans le forum, les offres d'emploi, les livres en vente, etc. Toutes ces données sont sans arrêt lues, écrites, modifiées ou supprimées, et ce serait mission impossible sans un système de stockage efficace.

Ce système miracle, c'est la base de données : elle permet d'enregistrer des données de façon organisée et hiérarchisée.

Structure

La base de données (BDD, ou DB en anglais) est un système qui enregistre des informations, mais pas n'importe comment : ces informations sont toujours classées. Et c'est ça qui fait que la BDD est si pratique : c'est un moyen extrêmement simple de ranger des informations ! Grossièrement, une BDD peut être vue comme un ensemble de tableaux, des structures contenant donc des lignes et des colonnes et dans lesquelles nos données sont rangées.

Il existe un vocabulaire spécifique pour désigner les différents éléments composant une BDD :

  • la base désigne le volume englobant l'ensemble, la boîte qui contient tous les tableaux ;
  • une table désigne un tableau de données, elle contient des lignes et des colonnes ;
  • une entrée désigne une ligne ;
  • un champ désigne une colonne.

En résumé, une base peut contenir plusieurs tables, qui peuvent contenir plusieurs entrées, pouvant à leur tour contenir plusieurs champs. Voici par exemple ce à quoi pourrait ressembler une table regroupant des informations concernant les membres d'un site :

id

pseudo

email

age

1

Coyote

coyote@bipbip.com

25

2

Thunderseb

jadorejquery@unefois.be

24

3

Kokotchy

decapsuleur@biere.org

27

4

Marcel

marcel@laposte.net

47

Vous voyez bien ici qu'une table se représente parfaitement par un simple tableau. Dans cet exemple :

  • les champs sont les têtes de colonne, à savoir "id", "pseudo", "email" et "age" ;
  • chaque ligne du tableau est une entrée de la table ;
  • il n'y a que quatre entrées, mais une table peut très bien en contenir des millions !

À quoi sert le champ "id" ?

Il signifie identifiant, et permet de numéroter les entrées d'une table : mettre en place un tel champ n'est pas une obligation, mais si vous avez lu l'introduction aux clés primaires du cours de MySQL que je vous ai conseillé en introduction, vous savez déjà que cette pratique nous sera très utile lors de la conception de nos tables.

Où sont stockées les données ?

En effet, c'est bien gentil de tout planquer dans la grosse boîte "base de données", mais au final où sont enregistrés les tableaux et les données qu'ils contiennent ? Eh bien il n'y a rien de magique, tout cela est sauvegardé dans… des fichiers écrits sur le disque ! Seulement, ce ne sont pas de simples fichiers texte, ils ne sont en aucun cas destinés à être édités à la main par le développeur : leur format est bien particulier et dépend du système de gestion utilisé. La représentation en tableaux utilisée précédemment pour vous faire comprendre comment fonctionne une table ne doit pas vous induire en erreur : sous la couverture, les données sont ordonnées de manière bien plus complexe !

SGBD

Dans le dernier paragraphe, je vous ai parlé de système de gestion, qu'on raccourcit en SGBD. Vous devez savoir qu'il n'existe pas qu'une seule solution pour créer et gérer des bases de données. Voici une liste des principaux acteurs de ce marché :

  • MySQL : solution libre et gratuite, c'est le SGBD le plus répandu. C'est d'ailleurs celui que nous allons utiliser dans ce cours !
  • PostgreSQL : solution libre et gratuite, moins connue du grand public mais proposant des fonctionnalités inexistantes dans MySQL ;
  • Oracle : solution propriétaire et payante, massivement utilisée par les grandes entreprises. C'est un des SGBD les plus complets, mais un des plus chers également ;
  • SQL Server : la solution propriétaire de Microsoft ;
  • DB2 : la solution propriétaire d'IBM, utilisée principalement dans les très grandes entreprises sur des Mainframes.

Comment choisir un SGBD ?

Comme pour tout choix de technologie, la décision peut être influencée par plusieurs contraintes : coût, performances, support, etc. Retenez simplement que dans la très grande majorité des cas, MySQL ou PostgreSQL répondront parfaitement et gratuitement à vos besoins !

Comment fonctionne un SGBD ?

Chaque système utilise un ensemble d'algorithmes pour trier et stocker les informations et pour y accéder, via des requêtes écrites en langage SQL. Un tel ensemble porte un nom bien particulier : le moteur de stockage. Il y a beaucoup à dire sur ce sujet : plutôt que de paraphraser, je vais vous demander de lire ce cours écrit par un autre membre du Site du Zéro, expliquant en détail quelles sont les solutions existantes pour le système MySQL, pourquoi elles existent et en quoi elles diffèrent : les moteurs de stockages de MySQL.

Dans notre projet, nous allons utiliser le moteur InnoDB, un moteur relationnel : il s'assure que les relations mises en place entre les données de plusieurs tables sont cohérentes et que si l'on modifie certaines données, ces changements seront répercutés aux tables liées.

SQL

Je vous ai expliqué que les tables et les données contenues dans une BDD étaient enregistrées dans des fichiers, mais que nous ne pouvions pas éditer ces fichiers à la main. Dans la pratique, nous n'irons en effet jamais toucher à ces fichiers directement : nous allons toujours déléguer cette tâche à MySQL. Dans les coulisses, c'est lui qui se débrouillera pour classer nos informations. Et c'est bien là tout l'avantage des bases de données : nous n'aurons jamais à nous soucier de la manière dont seront organisées nos données, nous nous contenterons de donner des ordres au SGBD.

Comment communiquer avec notre SGBD ?

Pour dialoguer avec lui, nous devons lui envoyer des requêtes écrites en langage SQL. Encore un nouveau langage à apprendre… La bonne nouvelle, c'est que le SQL est un standard, c'est-à-dire que peu importe le SGBD utilisé, vous devrez toujours lui parler en SQL. Le hic, c'est que d'un SGBD à l'autre, on observe quelques variantes dans la syntaxe des requêtes : rassurez-vous toutefois, cela ne concerne généralement que certaines commandes qui sont peu utilisées.

Le langage SQL n'est absolument pas lié au langage Java : c'est un langage à part entière, uniquement destiné aux bases de données. Pour vous donner une première idée de la syntaxe employée, voici un exemple de requête SQL :

1
SELECT id, nom, prenom, email FROM utilisateurs ORDER BY id;

Exemple

Nous sommes ici pour apprendre le Java EE, et malheureusement pour vous si vous ne connaissez pas encore les bases du langage SQL, je ne peux pas me permettre de disserter sur le sujet.

Heureusement, si vous souhaitez en savoir plus, comme je vous l'ai déjà dit en introduction il existe un cours de MySQL complet sur le Site du Zéro, qui vous guidera pas à pas dans votre apprentissage du langage. Lorsque vous vous sentirez à l'aise avec le sujet, vous serez alors capables de donner n'importe quel ordre à votre base de données, et serez donc capables de comprendre intégralement les exemples de ce cours sans aucune difficulté ! ;)

Préparation de la base avec MySQL

Installation

Pour commencer, vous devez vous rendre sur la page de téléchargement du site de MySQL. Sélectionnez alors le système d'exploitation sur lequel vous travaillez (Windows, Mac OS ou Linux, 32 bits ou 64 bits), et téléchargez la version de MySQL correspondante.

Sous Windows

Le plus simple est de choisir la version MySQL avec l'installeur MSI, et d'exécuter le fichier une fois téléchargé. L'assistant démarrera alors et vous guidera lors de l'installation. Lorsqu'il vous demandera de choisir entre trois types d'installation, vous choisirez "Typical". Arrivés à la fin de l'installation, une fenêtre vous demandera si vous souhaitez lancer l'assistant de configuration MySQL (voir la figure suivante).

Vous veillerez bien à cliquer sur la case à cocher entourée ci-dessus avant de cliquer sur le bouton Finish. Un assistant vous demandera alors de préciser quelles options vous souhaitez activer. Choisissez la configuration standard, et à l'étape suivante, cochez l'option "Include Bin Directory in Windows PATH", comme c'est indiqué sur la figure suivante.

L'outil vous proposera alors de définir un nouveau mot de passe pour l'utilisateur "root". Ne cochez aucune autre option à cette étape, et cliquez sur Execute pour lancer la configuration.

Sous Linux

Il vous suffit d'ouvrir un terminal et d'exécuter la commande suivante pour installer MySQL, ou son équivalent sous les distributions non debian-like :

1
sudo apt-get install mysql-server mysql-client

Une fois l'installation terminée, vous pourrez modifier le mot de passe par défaut de l'utilisateur "root" avec la commande suivante :

1
sudo mysqladmin -u root -h localhost password 'entrez ici votre mot de passe'

Sous Mac OS

Le plus simple pour ce système est de télécharger depuis le site de MySQL l'archive au format DMG. Ouvrez-la et vous y trouverez un fichier PKG dont le nom doit ressembler à mysql-5.5.27-osx10.6-x86.pkg, certains chiffres et extensions pouvant varier ou s'ajouter selon la version courante de MySQL lorsque vous procédez au téléchargement, et selon la configuration de votre poste. Il s'agit là de l'assistant d'installation de MySQL : exécutez-le, et suivez simplement les instructions qui vous sont données.

Une fois l'installation terminée, deux possibilités s'offrent à vous concernant la configuration du serveur : soit vous installez le package MySQL Startup Item, soit vous effectuez les manipulations à la main. Vous trouverez de plus amples détails concernant ces deux options sur cette page du site officiel dédiée à l'installation sous Mac OS X.

Création d'une base

Une fois le serveur MySQL installé sur votre poste, vous pouvez créer la base de données qui va nous servir dans toute la suite du cours. Nous allons en l'occurrence créer une base nommée bdd_sdzee, et initialiser l'encodage par défaut à UTF-8. Souvenez-vous, il s'agit là de l'encodage qui permettra à votre application de manipuler la plus grande variété de caractères :

1
CREATE DATABASE bdd_sdzee DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

Requête de création de la base

Création d'un utilisateur

Par défaut, MySQL propose un compte root qui donne accès à l'intégralité du serveur. C'est une très mauvaise pratique de travailler via ce compte, nous allons donc créer un utilisateur spécifique à notre application, qui n'aura accès qu'à la base sur laquelle nous travaillons :

1
2
CREATE USER 'java'@'localhost' IDENTIFIED BY 'SdZ_eE';
GRANT ALL ON bdd_sdzee.* TO 'java'@'localhost' IDENTIFIED BY 'SdZ_eE';

Requête de création de l'utilisateur

Ici le compte créé se nomme java, a pour mot de passe SdZ_eE et dispose de tous les droits sur la base bdd_sdzee. Vous pouvez bien entendu changer le mot de passe si celui-là ne vous plaît pas. :)

Pour l'utiliser, il faut ensuite vous déconnecter via la commande exit, et vous connecter à nouveau via la commande mysql -h localhost -u java -p, et enfin entrer la commande use bdd_sdzee.

Création d'une table

Maintenant que la base est prête et que nous avons créé et utilisons un compte, nous pouvons mettre en place une table qui va nous servir dans les exemples du chapitre à venir. Nous allons créer une table qui représente des utilisateurs, comportant un identifiant, une adresse mail, un mot de passe, un nom et une date d'inscription :

1
2
3
4
5
6
7
8
9
CREATE TABLE  bdd_sdzee.Utilisateur (
 id INT( 11 ) NOT NULL AUTO_INCREMENT ,
 email VARCHAR( 60 ) NOT NULL ,
 mot_de_passe VARCHAR( 32 ) NOT NULL ,
 nom VARCHAR( 20 ) NOT NULL ,
 date_inscription DATETIME NOT NULL ,
 PRIMARY KEY ( id ),
 UNIQUE ( email )
) ENGINE = INNODB;

Requête de création de la table

Vous pouvez ensuite vérifier la bonne création de la table nommée Utilisateur avec les commandes SHOW tables; et DESCRIBE Utilisateur;.

Insertion de données d'exemple

Afin de pouvoir commencer en douceur la manipulation d'une base de données depuis notre application dans le chapitre suivant, nous allons ici directement mettre en place quelques données factices, qui nous serviront d'exemple par la suite :

1
2
INSERT INTO Utilisateur (email, mot_de_passe, nom, date_inscription) VALUES ('coyote@mail.acme', MD5('bipbip'), 'Coyote', NOW());
INSERT INTO Utilisateur (email, mot_de_passe, nom, date_inscription) VALUES ('jadorejquery@unefois.be', MD5('avecdesfrites'), 'Thunderseb', NOW());

Requêtes d'insertion de données

Vous pouvez ensuite vérifier la bonne insertion des données dans la table via la commande SELECT * FROM Utilisateur; (voir la figure suivante).

Mise en place de JDBC dans le projet

Nous sommes capables de créer des bases et des tables dans MySQL, mais notre mission maintenant c'est bien entendu d'effectuer la liaison entre MySQL et notre projet Java EE. Car ce que nous souhaitons, c'est pouvoir interagir avec les tables de notre base bdd_sdzee directement depuis le code de notre application !

JDBC

La solution standard se nomme JDBC : c'est une API qui fait partie intégrante de la plate-forme Java, et qui est constituée de classes permettant l'accès depuis vos applications Java à des données rangées sous forme de tables. Dans la très grande majorité des cas, il s'agira bien entendu de bases de données stockées dans un SGBD ! Les actions rendues possibles par cette API sont :

  • la connexion avec le SGBD ;
  • l'envoi de requêtes SQL au SGBD depuis une application Java ;
  • le traitement des données et éventuelles erreurs retournées par le SGBD lors des différentes étapes du dialogue (connexion, requête, exécution, etc.).

Seulement, comme vous le savez, il existe plusieurs SGBD différents et bien qu'ils se basent tous sur le langage SQL, chacun a sa manière de gérer les données. L'avantage de JDBC, c'est qu'il est nativement prévu pour pouvoir s'adapter à n'importe quel SGBD ! Ainsi pour faire en sorte que notre application puisse dialoguer avec MySQL, nous aurons simplement besoin d'ajouter à notre projet un driver qui est spécifique à MySQL.

Si nous utilisions PostgreSQL, il nous faudrait, à la place, ajouter un driver propre à PostgreSQL, etc. Dans la pratique c'est très simple, il s'agit tout bonnement d'une archive .jar que nous allons ajouter au build-path de notre projet !

Pour information, sachez que JDBC ne fait pas uniquement partie de la plate-forme Java EE, c'est une brique de base de la plate-forme standard Java SE. Cependant, bien que ce cours se consacre à l'apprentissage du Java EE, j'ai jugé qu'il était préférable de s'y attarder, afin que ceux d'entre vous qui ne sont pas habitués à créer des applications Java faisant intervenir une base de données puissent découvrir et appliquer sereinement le principe par la suite. Après tout, cette brique rentre parfaitement dans le cadre de ce que nous étudions dans ce cours, à savoir la création d'une application web !

Mise en place

Pour commencer, il faut récupérer le driver sur la page de téléchargement du site de MySQL (voir la figure suivante).

Téléchargement du driver MySQL

Téléchargez alors l'archive au format que vous préférez. Décompressez son contenu dans un dossier sur votre poste, il contiendra alors un fichier mysql-connector-java-xxx-bin.jar (les xxx variant selon la version courante au moment où vous effectuez ce téléchargement).

Il suffit ensuite de copier ce fichier dans le répertoire /lib présent dans le dossier d'installation de votre Tomcat, et tous les projets déployés sur ce serveur pourront alors communiquer avec une base de données MySQL.

Au lieu de déposer le driver directement dans le dossier de bibliothèques du serveur d'applications, vous pouvez également passer par Eclipse et le placer uniquement dans le répertoire /WEB-INF/lib d'un projet en particulier. Eclipse va alors automatiquement ajouter l'archive au classpath de l'application concernée.

Toutefois, je vous recommande d'utiliser la première méthode. Cela vous permettra de ne pas avoir à inclure le driver dans chacun de vos projets communicant avec une base de données MySQL.

Création d'un bac à sable

Afin de pouvoir découvrir tranquillement le fonctionnement de JDBC, nous allons mettre en place un espace de tests dans notre application. Comme je vous l'ai dit, JDBC est une brique de la plate-forme Java SE, nous pourrions donc très bien nous créer un nouveau projet Java à part entière et y faire nos tests, avant de revenir à notre projet Java EE. Cependant, je préfère vous faire manipuler directement au sein de notre application, ça vous permettra de pratiquer une nouvelle fois la mise en place des différents composants habituels. Nous allons en l'occurrence avoir besoin :

  • d'un objet Java, qui contiendra le code de nos essais de manipulation de la base de données ;
  • d'une servlet, qui se contentera d'appeler les exemples présents dans l'objet Java ;
  • d'une page JSP, qui affichera enfin les résultats de nos différentes manipulations.

Création de l'objet Java

Pour commencer, mettons en place un nouvel objet Java nommé TestJDBC, dans un nouveau package nommé com.sdzee.bdd :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package com.sdzee.bdd;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

public class TestJDBC {
    /* La liste qui contiendra tous les résultats de nos essais */
    private List<String> messages = new ArrayList<String>();

    public List<String> executerTests( HttpServletRequest request ) {
        /* Ici, nous placerons le code de nos manipulations */
        /* ... */

        return messages;
    }
}

com.sdzee.bdd.TestJDBC

Celui-ci contient une seule méthode, vide pour le moment. C'est dans cette méthode que nous allons, par la suite, placer le code de nos manipulations, et c'est cette méthode qui sera appelée par notre servlet. La seule chose qu'elle retourne est une liste de messages, qui seront récupérés par la servlet.

Création de la servlet

Nous avons besoin d'une servlet pour appeler les tests écrits dans notre objet Java. Cette servlet sera déclenchée par un accès depuis votre navigateur à l'URL http://localhost:8080/pro/testjdbc.

Voici donc sa déclaration dans le fichier web.xml de notre application :

1
2
3
4
5
6
7
8
9
<servlet>
    <servlet-name>GestionTestJDBC</servlet-name>
    <servlet-class>com.sdzee.servlets.GestionTestJDBC</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>GestionTestJDBC</servlet-name>
    <url-pattern>/testjdbc</url-pattern>
</servlet-mapping>

/WEB-INF/web.xml

Et voici son code :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.sdzee.servlets;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sdzee.bdd.TestJDBC;

public class GestionTestJDBC extends HttpServlet {
    public static final String ATT_MESSAGES = "messages";
    public static final String VUE          = "/WEB-INF/test_jdbc.jsp";

    public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
        /* Initialisation de l'objet Java et récupération des messages */
        TestJDBC test = new TestJDBC();
        List<String> messages = test.executerTests( request );

        /* Enregistrement de la liste des messages dans l'objet requête */
        request.setAttribute( ATT_MESSAGES, messages );

        /* Transmission vers la page en charge de l'affichage des résultats */
        this.getServletContext().getRequestDispatcher( VUE ).forward( request, response );
    }
}

com.sdzee.servlets.GestionTestJDBC

Elle se contentera d'appeler la méthode de notre nouvel objet Java à chaque requête GET reçue, autrement dit, chaque fois que nous accéderons depuis notre navigateur à l'URL que nous avons définie précédemment. Elle récupérera lors de cet appel la liste des messages créés par le code de nos essais, et la transmettra alors à une page JSP pour affichage.

Création de la page JSP

Enfin, nous avons besoin d'une page qui aura pour unique mission d'afficher les messages retournés par nos différents tests, que nous allons nommer test_jdbc.jsp et que nous allons placer sous /WEB-INF :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Tests JDBC</title>
        <link type="text/css" rel="stylesheet" href="<c:url value="/inc/form.css"/>" />
    </head>
    <body>
        <h1>Tests JDBC</h1>

        <c:forEach items="${ messages }" var="message" varStatus="boucle">
            <p>${ boucle.count }. ${ message }</p>
        </c:forEach>
    </body>
</html>

/WEB-INF/test_jdbc.jsp


  • Une base de données permet de stocker des données de manière organisée et hierarchisée.
  • L'utilisation de l'encodage UTF-8 pour stocker les données d'une application web est très recommandée.
  • Le driver JDBC permet l'interaction entre une application Java (web ou non) et une base de données.
  • Il existe un driver différent pour chaque type de base de données existant.
  • Il s'agit concrètement d'un simple fichier Jar, à placer dans le répertoire /lib du serveur d'applications.