Blog ENI : Toute la veille numérique !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
💥 Du 22 au 24 novembre : Accès 100% GRATUIT
à la Bibliothèque Numérique ENI. Je m'inscris !
  1. Livres et vidéos
  2. Struts 2
  3. Les bases de données avec Java EE
Extrait - Struts 2 Développez votre application web moderne avec Java
Extraits du livre
Struts 2 Développez votre application web moderne avec Java Revenir à la page d'achat du livre

Les bases de données avec Java EE

Modélisation de la base de données avec UML 2

Comme dans tout projet de développement d’application, il est primordial de bien penser et de bien concevoir en amont une base de données adaptée au besoin.

En effet, une base de données bien modélisée permet à la fois d’optimiser les requêtes SQL et le code d’un point de vue de la performance et de la maintenabilité.

1. Cahier des charges

L’objectif est de modéliser une base de données objet à l’aide d’UML 2.

Tout d’abord, nous allons lister les principales fonctionnalités attendues par les utilisateurs. Il va en découler naturellement les différentes tables à créer, implémenter, les relations entre elles et les différentes autres contraintes.

L’application web Java Devis Pro BTP permet à un artisan de gérer son portefeuille client, d’éditer des devis et des factures correspondant aux travaux qu’il va réaliser ou qu’il a réalisés.

Voici ci-dessous les principales fonctionnalités de l’application :

  • créer un devis,

  • consulter un devis,

  • modifier un devis,

  • supprimer un devis,

  • envoyer le devis à un client,

  • ajouter un nouveau client,

  • consulter une fiche client,

  • rechercher un client à partir de son nom,

  • mettre à jour les informations relatives à un client,

  • supprimer une fiche client,

  • créer une facture,

  • consulter une facture,

  • modifier une facture,

  • supprimer une facture,

  • rechercher une facture,

  • gérer son profil artisan,

  • se connecter,

  • se déconnecter,

  • changer son mot de passe,

  • gérer le mot de passe et l’identifiant perdus.

2. Interface utilisateur

Afin de modéliser au mieux le besoin utilisateur, il est intéressant de s’appuyer dès à présent sur quelques...

Design pattern DAO

L’implémentation du design pattern DAO (Data Access Object) s’appuie sur l’utilisation de JDBC.

Le JDBC DriverManager est en fait une implémentation du design pattern DAO.

1. Description

Le design pattern DAO est très largement implémenté pour gérer la persistance des données lors du développement d’une application.

La classe CommonDAO décrit les méthodes génériques de création, mise à jour, consultation et suppression des données en base de données.

Chaque objet métier a son DAO afin d’effectuer différentes opérations en base de données. Ainsi l’objet Client a son DAO, que nous nommons ClientDAO, dans lequel sont implémentées les méthodes dont il a hérité, telles que la création, la suppression, la mise à jour et la consultation des données relatives aux clients.

Sur le même principe les objets Artisan, Devis, Facture, Client et les autres ont également leur DAO pour, eux aussi, avoir accès aux différentes opérations à effectuer en base de données.

Nous allons créer la classe abstraite CommonDAO, chaque DAO métier héritera de cette classe.

Voici ci-dessous le diagramme de classe modélisant les DAO :

images/04ET04.png

2. Classe Client

Nous nous appuyons sur la classe Client décrite dans le schéma de la base de données vu précédemment dans ce chapitre. Nous nommons cette classe Client.java.

D’un point de vue arborescence du projet de l’application web devisprobtp, cette classe Java est à créer sous Source Packages/devisprobtp.javabeans.

images/04ET05.png

La classe Client est une classe qui fait partie du modèle d’un point de vue du design pattern MVC. Elle a pour rôle de décrire ce qui constitue...

Connexion à la base de données

1. Pattern singleton

Le principe de base du design pattern singleton est de rendre unique l’instanciation d’une classe afin d’en limiter le nombre et même mieux, de n’autoriser qu’une connexion à la base de données dans notre cas.

Cela est techniquement possible en déclarant le constructeur en privé dans la classe Java private).

Par conséquent, pour accéder à la classe connection, nous définissons une méthode publique getInstance qui, elle seule, sera accessible.

Voici, ci-dessous, un exemple :

/*  
* Singleton design pattern  
*/  
  
public class MyConnection{  
 //URL  
 private String url = "jdbc:postgresql://localhost:5432/devisprobtp"; 
 //User Name  
 private String user = "admin devisprobtp";  
 //User password  
 private String passwd = " devisprobtp";  
 //Connection Object  
 private static Connection connect;  
    
 //Private Constructor  
 private MyConnection(){  
   try {  
     connect = DriverManager.getConnection(url, user, passwd); 
   } catch (SQLException e) {  
     e.printStackTrace();  
   }  
 }   
 //Retrun the instance or ceate if if doesn't exist  
  public static Connection getInstance(){  
   if(connect == null){  
     new MyConnection();  
   }  
   return connect;  
 }  
} 

Dans notre cas de figure, c’est la classe ConnectionBDPostgreSQL.java...

Persistance des données

1. Ajouter un client

Si vous souhaitez ajouter un nouveau client en base de données :

 Implémentez la méthode qui permet d’ajouter un enregistrement dans la table Client.

 En amont, implémentez la requête SQL d’insertion d’un client dans la table Client dans le fichier Client.java.

package devisporbtp.modeles; 
 
/** 
 * 
 * @author cdavezac 
 */ 
public class SQLConstant { 
 
    protected static final String INSERT__CLIENT = 
"INSERT INTO CLIENT(clientId, nom, prenom, adresse, telephone, 
email, artisanId) VALUES (DEFAULT, ?,?,?,?,?,?)"; 
 
} 

 Puis, faites évoluer la classe Java ClientDAO.java en implémentant la méthode create, qui permet d’ajouter un auteur en base de données.

package devisprobtp.modeles;  
  
import devisprobtp.javabeans.Author;  
import java.sql.Connection;  
import java.sql.PreparedStatement;  
import java.sql.ResultSet;  
import java.sql.SQLException;  
import java.util.ArrayList;  
import java.util.Iterator;  
import java.util.logging.Level;  
import java.util.logging.Logger;  
  
  
public class ClientDAO extends CommonDAO<Client>{  
  
        public Clientcreate(Client client) {  
        try{  
           //Creation of the PreparedStatement  
           PreparedStatement statement = connection.prepareStatement  
               (SQLConstant.INSERT_CLIENT);  
  
//Insert parameter at the location of the question mark in the SQL Query ...

Requête paramétrée, tri, pagination

1. Requête paramétrée

Les PreparedStatement sont des requêtes SQL pré-compilées que l’on peut paramétrer. Ces paramètres d’entrée sont spécifiés dans la requête par un point d’interrogation.

a. Implémentation SQL

Voici un exemple de requête SQL paramétrée. Cette requête permet l’insertion de nouveaux clients dans la table Client. Les données à insérer sont représentées par des points d’interrogation car elles seront paramétrables.

INSERT INTO CLIENT(clientId, nom, prenom, adresse, telephone, 
email) VALUES(?,?,?,?,?,?)"; 

Les requêtes préparées permettent à la fois un gain de conception et de qualité : on conçoit la requête une seule fois car les paramètres sont variables. Elles permettent également d’améliorer grandement la rapidité d’exécution car elles ne sont compilées qu’une seule fois.

Tout l’intérêt des requêtes préparées repose dans le fait qu’elles sont utilisées plusieurs fois.

b. Implémentation Java

L’interface PreparedStatement est une sous-interface de l’interface Statement. Elle est utilisée pour exécuter une requête paramétrée.

Voici, ci-dessous, un exemple de requête préparée :

//Requête pour créer un nouveau client 
/** Requête SQL de recherche de tous les clients */ 
protected static final String ADD_CLIENT = "INSERT INTO  
CLIENT(clientId, nom, prenom, adresse, telephone, email)  
VALUES(?,?,?,?,?,?)"; 

Ici le paramètre (?) est spécifié pour désigner les valeurs dynamiques. Elles...

Gestion des transactions

Une transaction est un ensemble de modifications de la base.

Les opérations plus courantes sont : BEGIN, COMMIT, ROLLBACK.

1. Introduction

Les transactions SQL doivent répondre aux propriétés ACID (atomicité, cohérence, isolation et durabilité). Ce sont un ensemble de propriétés qui garantissent qu’une transaction informatique est exécutée de façon fiable :

  • L’atomicité : les transactions constituent l’unité logique de travail, toute la transaction est exécutée ou bien pas du tout, mais jamais une partie seulement de la transaction.

  • La cohérence : les transactions préservent la cohérence de la base de données, c’est-à-dire qu’elles transforment la base de données d’un état cohérent à un autre.

  • L’isolation, les transactions sont isolées les unes des autres, c’est-à-dire que leur exécution est indépendante des autres transactions en cours. Elles accèdent donc à la base de données comme si elles étaient seules à s’exécuter.

  • La durabilité : les transactions assurent que les modifications qu’elles induisent perdurent, même en cas de défaillance du système.

2. Gestion des transactions

Si on exécute des transactions, il faut que les actions engendrées sur la base de données s’effectuent complètement ou ne s’effectuent pas du tout afin de toujours laisser la base de données dans un état cohérent. Les systèmes de gestion de bases de données permettent aux utilisateurs de gérer leurs transactions, ils peuvent à tout moment valider ou annuler la transaction en cours.

a. Valider une transaction

Pour valider...

Utilisation du framework Hibernate

La couche d’accès aux données peut être implémentée à travers un framework objet/relationnel tel que Hibernate.

1. Installation du plug-in

 Lancez Eclipse, puis allez dans le menu Help - Eclipse Marketplace.

images/04ET06.png

 La fenêtre suivante s’affiche, dans la barre de recherche, saisissez hibernate :

images/04ET07.png

 Cliquez sur le bouton Install pour installer le plug-in. Désélectionnez tous les éléments, puis sélectionnez uniquement Hibernate Tools.

images/04ET08.png

 Cliquez sur Confirm, puis I accept the terms of the license agreements et enfin Finish.

2. Hibernate

Hibernate est une solution open source de type ORM (Object Relational Mapping) qui permet de faciliter le développement de la couche persistance d’une application. Hibernate permet donc de représenter une base de données en objets Java et vice versa.

Hibernate facilite la persistance et la recherche de données dans une base de données en réalisant lui-même la création des objets et les traitements de remplissage de ceux-ci en accédant à la base de données. La quantité de code ainsi épargnée est très importante, d’autant que ce code est généralement fastidieux et redondant.

Hibernate est très populaire, notamment à cause de ses bonnes performances et de son ouverture à de nombreuses bases de données.

Les bases de données supportées sont les principales du marché, dont PostgreSQL.

Voici un schéma récapitulatif de l’architecture de notre application web Java responsive devis pro btp.

images/04ET09.png

Nous allons utiliser Hibernate avec notre base de données PostgreSQL devisprobtp.

3. Équivalence table/objet

Pour faire fonctionner Hibernate, il y a trois étapes à mettre en œuvre :...

Bonnes pratiques et mise en cache

1. Bonnes pratiques

Dans ce chapitre, sont présentées de façon non exhaustive, quelques bonnes pratiques SQL permettant une meilleure lisibilité et maintenance des requêtes SQL et un amélioration des performances lors de l’exécution des requêtes.

a. Formatage du code SQL

SQL est un langage à part entière, il se doit d’utiliser les règles de formatage et d’écriture comme cela est le cas pour n’importe quel langage de programmation. Pour cela il convient de distinguer les mots-clés du langage des identifiants de colonnes et de tables, en utilisant l’indentation et les commentaires.

Voici un exemple :

select clientId, nom, prenom from client where artisanId = 5 order by nom; 
 
/* Cette requête est strictement identique mais est bien plus lisible */ 
 
SELECT clientId, nom, prenom 
FROM client 
WHERE artisanId = 5 
ORDER BY nom ; 

Pour en savoir plus, référez-vous au guide de style SQL disponible au lien suivant : https://www.sqlstyle.guide/

b. Limiter le volume de données manipulé

Le volume de données récupéré a un impact sur les performances. Lors de l’écriture d’une requête SQL, il est donc recommandé de n’accéder qu’aux tables et aux colonnes nécessaires. Il faut également avoir à l’esprit que plus le volume de données à traiter est élevé, plus les opérations seront lentes : les tris et jointures et, éventuellement, le stockage temporaire sur disque pour certains algorithmes.

Par exemple, si nous devonst récupérer uniquement le nom du client nous n’utiliserons pas SELECT * FROM client, qui ramène tous les champs, mais SELECT nom FROM client.

Il faudra également...