Documentation – Application Java JDBC avec MySQL
Documentation Complète
Application Java – Gestion de Patients avec JDBC & MySQL
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Guide pédagogique étape par étape
Adapté aux débutants en programmation Java
Cours : Programmation Orientée Objet & Bases de Données
Technologies : Java SE • Swing • JDBC • MySQL Connector/J
Ce document contient :
• Présentation générale du projet et de son architecture
• Analyse ligne par ligne du code bugué (avec identification des erreurs)
• Explication complète du code corrigé
• Tableau récapitulatif des 8 bugs et leurs corrections
• Script SQL commenté pour MySQL
• Conseils et bonnes pratiques
Page 1 / 13
Documentation – Application Java JDBC avec MySQL
PARTIE 1 – Présentation Générale du Projet
1.1 Objectif de l'application
Cette application Java a pour but de permettre la saisie et l'enregistrement de données médicales de patients
dans une base de données MySQL. Elle est réalisée avec la bibliothèque graphique Swing (interface visuelle)
et JDBC (Java Database Connectivity) pour la communication avec la base de données.
Concrètement, l'utilisateur remplit un formulaire contenant :
• Un identifiant (Id)
• Un prénom
• Un nom
• Un âge
• Une adresse
Il appuie ensuite sur le bouton Valider pour enregistrer les données dans la base, ou sur Annuler pour tout
effacer.
1.2 Technologies utilisées
Technologie Rôle dans le projet
Java SE Langage de programmation principal
Swing Création de l'interface graphique (fenêtre, boutons, champs)
([Link])
JDBC API Java pour connecter le programme à la base de données
MySQL Connector/J Driver (pilote) qui permet à Java de parler à MySQL
MySQL Système de gestion de base de données (SGBD)
1.3 Structure du code
Le programme est organisé autour d'une seule classe Java nommée exo1. Cette classe hérite de JFrame (ce
qui lui permet d'être une fenêtre graphique) et implémente ActionListener (ce qui lui permet de réagir aux clics
sur les boutons).
La classe contient trois parties principales :
1. Le constructeur exo1() : configure la fenêtre et construit l'interface graphique
2. La méthode actionPerformed() : gère les actions (clic sur Valider ou Annuler)
3. La méthode main() : point d'entrée du programme, crée et affiche la fenêtre
Page 2 / 13
Documentation – Application Java JDBC avec MySQL
PARTIE 2 – Analyse du Code Bugué
⚠️ATTENTION : Le code original contient 8 erreurs qui empêchent le programme de compiler et de
fonctionner correctement. Nous allons les analyser une par une.
2.1 Code original (avec annotations des erreurs)
Voici le code tel qu'il a été fourni, avec les numéros des bugs identifiés :
package graphique;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
// ❌ BUG 3 : La classe n'implémente pas ActionListener
public class exo1 extends JFrame {
private static JTextField Id, prenom, nom, Age, Adresse;
private static JButton b1, b2;
private JPanel boiteDialogue; // ❌ BUG 7 : jamais initialisé
private static JPanel pannel, Fichier;
private static JLabel msg;
// ❌ BUG 1 : Le constructeur s'appelle tp() au lieu de exo1()
public tp() {
super("Applis des menus");
setSize(300, 300);
WindowListener l = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
[Link](1);
}
};
addWindowListener(l);
}
// ❌ BUG 5 : La méthode actionPerformed contient main() à l'intérieur !
public void actionPerformed(ActionEvent ev) {
if ([Link]() == b1) {
try {
// ❌ BUG 8 : Driver ODBC obsolète (remplacer par MySQL)
[Link]("[Link]").newInstance();
} catch (Exception exc) { [Link](0); }
Connection con = null;
try {
// ❌ BUG 8 (suite) : URL ODBC au lieu de URL MySQL
con = [Link]("jdbc:odbc:IPAIM", "", "");
} catch (SQLException ex) { [Link](0); }
...
Page 3 / 13
Documentation – Application Java JDBC avec MySQL
}
if ([Link]() == b2) {
// ❌ BUG implicite : bloc vide, aucune action pour Annuler
}
// ❌ BUG 5 (suite) : main() est DANS actionPerformed, ce qui est illégal !
public static void main(String[] args) {
// ❌ BUG 2 : Exo1 avec majuscule au lieu de exo1
Exo1 f = new exo1();
...
// ❌ BUG 4 : Les boutons n'ont pas de addActionListener()
// ❌ BUG 6 : [Link](true) est absent !
}
} // fin de actionPerformed – la classe n'est pas correctement fermée
2.2 Explication détaillée de chaque bug
BUG N°1 – Constructeur mal nommé
En Java, le constructeur d'une classe doit obligatoirement porter exactement le même nom que la classe. Si
la classe s'appelle exo1, le constructeur doit aussi s'appeler exo1().
Ce qui est écrit (incorrect) :
public tp() { // ← tp() ne correspond pas à exo1
Ce qui est attendu (correct) :
public exo1() { // ← même nom que la classe
Conséquence : le compilateur ne reconnaît pas tp() comme un constructeur et génère une erreur.
BUG N°2 – Mauvaise casse dans le main()
Java est sensible à la casse : Exo1 et exo1 sont deux noms complètement différents. Le main() essaie de
créer une instance de Exo1 (avec E majuscule) alors que la classe se nomme exo1 (avec e minuscule).
// ❌ Incorrect
Exo1 f = new exo1();
// ✅ Correct
exo1 f = new exo1();
BUG N°3 – Classe n'implémente pas ActionListener
Pour que la méthode actionPerformed() fonctionne, la classe doit déclarer qu'elle implémente l'interface
ActionListener. Sans cela, les boutons ne sauront jamais où envoyer leurs événements.
// ❌ Incorrect
public class exo1 extends JFrame {
// ✅ Correct
public class exo1 extends JFrame implements ActionListener {
BUG N°4 – Boutons sans ActionListener
Même si la classe implémente ActionListener, il faut explicitement dire à chaque bouton : 'quand on te clique,
appelle actionPerformed()'. Cela se fait avec addActionListener().
Page 4 / 13
Documentation – Application Java JDBC avec MySQL
// ❌ Incorrect – les boutons sont créés mais pas branchés
b1 = new JButton("Valider");
b2 = new JButton("Annuler");
// ✅ Correct – on branche les écouteurs
b1 = new JButton("Valider");
[Link](this); // 'this' = la classe courante (exo1)
b2 = new JButton("Annuler");
[Link](this);
BUG N°5 – main() imbriqué dans actionPerformed()
C'est l'erreur la plus grave structurellement. Le bloc de la méthode actionPerformed() n'est jamais fermé
correctement, ce qui fait que la méthode main() se retrouve physiquement à l'intérieur d'actionPerformed(). En
Java, une méthode ne peut pas contenir une autre méthode.
💡 Règle fondamentale : Chaque méthode doit être indépendante. Toutes les méthodes sont au
même niveau, à l'intérieur de la classe, mais jamais l'une dans l'autre.
Structure incorrecte :
public void actionPerformed(ActionEvent ev) {
if ([Link]() == b1) {
...
}
if ([Link]() == b2) {
}
// Ici il manque la fermeture } de actionPerformed !
public static void main(String[] args) { // ← ERREUR : main() est à l'intérieur !
...
}
} // ← ceci ferme actionPerformed, pas la classe
Structure correcte :
public void actionPerformed(ActionEvent ev) {
....
} // ← fermeture de actionPerformed
public static void main(String[] args) { // ← main() est indépendant
...
} // ← fermeture de main
BUG N°6 – setVisible(true) manquant
En Java Swing, créer un objet JFrame ne l'affiche pas automatiquement. Il faut explicitement appeler
setVisible(true) pour rendre la fenêtre visible à l'écran.
exo1 f = new exo1();
// ❌ Sans cette ligne, la fenêtre reste invisible
[Link](true); // ✅ À ajouter obligatoirement
Page 5 / 13
Documentation – Application Java JDBC avec MySQL
BUG N°7 – boiteDialogue non initialisé (null)
La variable boiteDialogue est déclarée (JPanel boiteDialogue;) mais jamais créée avec new JPanel(). En
Java, une variable non initialisée vaut null, ce qui provoque une NullPointerException au moment de l'utiliser.
// Dans le constructeur exo1(), ajouter :
boiteDialogue = new JPanel(); // ✅ initialisation obligatoire
BUG N°8 – Driver et URL ODBC obsolètes
Le code utilise l'ancien pilote JDBC-ODBC ([Link]) qui n'existe plus depuis Java 8.
Pour se connecter à MySQL, il faut utiliser le pilote officiel MySQL Connector/J.
❌ Ancien code (ODBC – ne fonctionne plus) ✅ Nouveau code (MySQL Connector/J)
[Link]("[Link]"); [Link]("[Link]");
[Link]("jdbc:odbc:IPAIM"," [Link]("jdbc:mysql://
",""); localhost:3306/IPAIM","root","");
Page 6 / 13
Documentation – Application Java JDBC avec MySQL
PARTIE 3 – Tableau Récapitulatif des 8 Bugs
Ce tableau résume tous les bugs identifiés, leur localisation dans le code et la correction à apporter.
# Problème Dans le code bugué Correction apportée
1 Constructeur mal public tp() { public exo1() {
nommé
2 Mauvaise casse dans Exo1 f = new exo1(); exo1 f = new exo1();
main()
3 ActionListener non class exo1 extends JFrame { class exo1 extends JFrame
implémenté implements ActionListener {
4 Boutons sans listener b1 = new JButton(...); [Link](this);
5 main() dans Méthodes imbriquées illégales Deux méthodes séparées et
actionPerformed() indépendantes
6 Fenêtre invisible new exo1(); (sans visible) [Link](true);
7 boiteDialogue null JPanel boiteDialogue; boiteDialogue = new JPanel();
8 Driver ODBC obsolète [Link] [Link]
Page 7 / 13
Documentation – Application Java JDBC avec MySQL
PARTIE 4 – Analyse du Code Corrigé
✅ NOTE : Le code corrigé est présenté section par section avec des explications pédagogiques
pour chaque bloc.
4.1 Déclaration de la classe
public class exo1 extends JFrame implements ActionListener {
• public class exo1 : on déclare une classe publique nommée exo1
• extends JFrame : la classe hérite de JFrame → elle EST une fenêtre graphique
• implements ActionListener : la classe s'engage à réagir aux événements de boutons
4.2 Déclaration des variables
private JTextField Id, prenom, nom, Age, Adresse;
private JButton b1, b2;
private JPanel boiteDialogue;
private JPanel pannel, Fichier;
private JLabel msg;
Chaque composant de l'interface est déclaré comme attribut de la classe (non static) pour être accessible
depuis toutes les méthodes.
• JTextField : champ de saisie de texte
• JButton : bouton cliquable
• JPanel : panneau conteneur
• JLabel : étiquette de texte
4.3 Le constructeur exo1()
public exo1() {
super("Applis des menus"); // Titre de la fenêtre
setSize(300, 300); // Dimensions : 300x300 pixels
boiteDialogue = new JPanel(); // ✅ Initialisation
// Gestionnaire de fermeture de fenêtre
WindowListener l = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
[Link](1); // Quitter le programme
}
};
addWindowListener(l);
// Construction de l'interface...
Fichier = new JPanel();
[Link](new Dimension(250, 300));
// ... (ajout des composants)
[Link](this); // ✅ Branchement des boutons
[Link](this);
Page 8 / 13
Documentation – Application Java JDBC avec MySQL
add(Fichier); // Ajout du panneau à la fenêtre
}
4.4 La méthode actionPerformed()
Cette méthode est appelée automatiquement chaque fois qu'un bouton est cliqué. Elle contient la logique de
connexion à la base de données.
@Override
public void actionPerformed(ActionEvent ev) {
if ([Link]() == b1) { // Clic sur 'Valider'
// ÉTAPE 1 : Charger le driver MySQL
try {
[Link]("[Link]");
} catch (Exception exc) {
[Link](this, "Erreur driver MySQL");
[Link](0);
}
// ÉTAPE 2 : Se connecter à la base de données
Connection con = null;
try {
con = [Link](
"jdbc:mysql://localhost:3306/IPAIM", "root", "");
} catch (SQLException ex) {
[Link](this, "Connexion impossible");
[Link](0);
}
// ÉTAPE 3 : Demander confirmation et insérer
try {
int i = [Link](
boiteDialogue, "Voulez-vous effectuer cette opération ?",
"CONFIRMATION", JOptionPane.OK_CANCEL_OPTION);
if (i == JOptionPane.OK_OPTION) {
Statement pst = [Link]();
String sql = "INSERT INTO Patients VALUES ('"
+ [Link]() + "','" + [Link]() + "',"
+ "'" + [Link]() + "','" + [Link]()
+ "','" + [Link]() + "')";
[Link](sql);
[Link]("** Exécution avec succès **");
// Vider les champs après insertion
[Link](""); [Link]("");
[Link](""); [Link](""); [Link]("");
[Link](); [Link]();
}
} catch (Exception sq) {
[Link](
boiteDialogue, "Impossible d'exécuter",
"Message", JOptionPane.INFORMATION_MESSAGE, null);
Page 9 / 13
Documentation – Application Java JDBC avec MySQL
}
}
if ([Link]() == b2) { // Clic sur 'Annuler'
[Link](""); [Link]("");
[Link](""); [Link](""); [Link]("");
[Link]("");
}
}
4.5 La méthode main()
public static void main(String[] args) {
exo1 f = new exo1(); // Crée la fenêtre
[Link](true); // ✅ L'affiche à l'écran
}
💡 À retenir : Le main() est le point d'entrée du programme. Il se contente de créer une instance de
la classe et de la rendre visible. Toute la logique est dans le constructeur et dans actionPerformed().
Page 10 / 13
Documentation – Application Java JDBC avec MySQL
PARTIE 5 – Script SQL pour MySQL
5.1 Création de la base et de la table
-- Créer la base de données (si elle n'existe pas déjà)
CREATE DATABASE IF NOT EXISTS IPAIM;
-- Sélectionner la base
USE IPAIM;
-- Créer la table Patients
CREATE TABLE Patients (
Id VARCHAR(10) PRIMARY KEY, -- Identifiant unique
Prenom VARCHAR(50) NOT NULL, -- Prénom obligatoire
Nom VARCHAR(50) NOT NULL, -- Nom obligatoire
Age VARCHAR(3) NOT NULL, -- Age (ex: '25')
Adresse VARCHAR(100) NOT NULL -- Adresse complète
);
5.2 Requêtes de test
-- Insérer un patient de test
INSERT INTO Patients VALUES ('001', 'Moussa', 'Diallo', '30', 'Dakar');
-- Afficher tous les patients
SELECT * FROM Patients;
-- Chercher par nom
SELECT * FROM Patients WHERE Nom = 'Diallo';
-- Modifier l'adresse d'un patient
UPDATE Patients SET Adresse = 'Thiès' WHERE Id = '001';
-- Supprimer un patient
DELETE FROM Patients WHERE Id = '001';
5.3 Correspondance Java ↔ SQL
Champ Java (JTextField) Colonne SQL (Patients) Type MySQL
[Link]() Id VARCHAR(10) PRIMARY KEY
[Link]() Prenom VARCHAR(50)
[Link]() Nom VARCHAR(50)
[Link]() Age VARCHAR(3)
[Link]() Adresse VARCHAR(100)
Page 11 / 13
Documentation – Application Java JDBC avec MySQL
PARTIE 6 – Bonnes Pratiques et Conseils
6.1 Sécurité – Utiliser PreparedStatement
Le code actuel construit la requête SQL par concaténation de chaînes de caractères, ce qui expose à une
faille de sécurité grave appelée injection SQL.
⚠️Injection SQL : Un utilisateur malveillant pourrait taper ' OR '1'='1 dans un champ pour accéder
à toutes les données ou détruire la base.
La solution recommandée est d'utiliser un PreparedStatement :
// ❌ Dangereux (concaténation directe)
[Link]("INSERT INTO Patients VALUES ('" + [Link]() + "',...)");
// ✅ Sécurisé (PreparedStatement)
PreparedStatement pst = [Link](
"INSERT INTO Patients VALUES (?, ?, ?, ?, ?)");
[Link](1, [Link]());
[Link](2, [Link]());
[Link](3, [Link]());
[Link](4, [Link]());
[Link](5, [Link]());
[Link]();
6.2 Organisation du code
• Déplacer la construction de l'interface dans le constructeur (pas dans main)
• Créer une méthode dédiée connecterBD() pour la connexion à la base
• Éviter les attributs static inutiles
• Fermer les connexions dans un bloc finally pour garantir leur fermeture
6.3 Gestion des erreurs
• Afficher des messages d'erreur clairs à l'utilisateur plutôt que [Link]()
• Logger les exceptions pour faciliter le débogage
• Vérifier que les champs ne sont pas vides avant d'insérer
6.4 Checklist de débogage rapide
✓ Vérification à faire
□ Le constructeur porte-t-il exactement le même nom que la classe ?
□ La classe implémente-t-elle ActionListener ?
□ Chaque bouton a-t-il un addActionListener(this) ?
□ Les accolades {} sont-elles correctement équilibrées (une ouvrante = une fermante) ?
□ setVisible(true) est-il appelé dans le main() ?
Page 12 / 13
Documentation – Application Java JDBC avec MySQL
✓ Vérification à faire
□ Tous les objets (JPanel, etc.) sont-ils initialisés avec new ?
□ Le jar MySQL Connector/J est-il dans le classpath du projet ?
□ L'URL JDBC pointe-t-elle vers le bon hôte, port et nom de base ?
— Fin de la documentation —
Page 13 / 13