Archives Wild Code School
Java Avancé

JDBC

Quête 9 sur 15

Cette quête va te permettre de faire évoluer ton appli GithubTracker en y ajoutant une BD pour pouvoir faire un vrai suivi de githubers. Tu vas découvrir l'API Java principale pour interagir avec une BD: JDBC .

Objectifs

  • Prendre en main l'API JDBC
  • Savoir utiliser une DataSource pour récupérer une connexion

Parquer les Githubers en BD

Où en étions nous déjà: tu as une appli qui affiche une liste de githubers, avec une classe (MemoryGithuberDAO) qui te permet de récupérer des infos par le biais de l'api Github, le tout (la classe!) , injecté directement dans une servlet par le biais de la classe GithuberService. Tu peux également ajouter un nouveau githuber à l'aide de la servlet TrackServlet.

A présent, pour ne pas avoir à recommencer la saisie des githubers à chaque redémarrage de l'appli (même si c'est très fun je te l'accorde), tu vas "persister" dans une BD les githubers à "tracker", histoire de pouvoir effectuer un vrai suivi dans le temps.

Tu vas donc créer la BD githubtracker sur ton mysql local. Dans un premier temps, tu vas y définir une seule table. Oui, tu l'as deviné, celle là oui, exactement, bien vu: la table githuber (et non pas mygithubuser, ou userfromgithub, ou myweirdnamedusertable, ou encore unNomSuperlongSansAucunRapportAvecLeSchmilblick etc ... si tu hésitais sur le nommage).

Fais en sorte de pouvoir y stocker au minimum les attributs suivant de ta classe Githuber:

shell
    - id (un auto increment mysql)
    - github_id (l'id fourni par l'api github)
    - name
    - login
    - url
    - email
    - bio
    - location
    - avatar_url

Vérifie que tu parviens à te connecter à ta base githubtracker et que tu peux bien voir et modifier les données de la table githuber. (Tu peux utiliser la ligne de commande ou MysqlWorkbench)

Au fait, sais-tu comment s'assurer que toute l'équipe d'un projet travaille tous sur la même structure de base de données ? Comment reproduire ce schéma simplement sur une nouvelle base voire sur un autre serveur?

Pour pouvoir répondre à ces exigences, en clair pour être sûr de pouvoir reproduire ton schéma de BD à l'envie, il faut en faire un script sql, qui va donc te permettre de créer le schéma githubtracker ainsi que cette première table (puis les autres éventuelles) en une seule ligne de commande. Une fois que ton script est au point et qu'il fonctionne, stocke le par exemple dans le sous répertoire db du répertoire ressources de ton projet. Et n'oublie pas de commiter et pusher. Ton code sql est du code à versioner tout comme ton code Java...

↗
SQL versioning
red-gate.com
↗
Syntaxe mysql
dev.mysql.com

Stocker et récupérer des Githubers en BD

Maintenant que ta BD est initialisée et disponible, tu vas pouvoir implémenter une nouvelle version du DAO Githuber (oui ça fait 3 oui) qui va exploiter cette BD : le JDBCGithuberDAO. Ce nouveau DAO va te permettre de stocker en BD les informations des githubers que tu souhaites suivre ainsi que de les récupérer lorsque tu en as besoin. Ainsi tu n'auras plus besoin de passer systématiquement par un appel à l'api Github quand tu veux simplement afficher la liste des githubers et ton appli aura enfin une "mémoire" entre 2 redémarrages. Tu peux donc commencer par implémenter les 2 méthodes de l'interface GithuberDAO:

  • void saveGithuber(Githuber githuber)qui crée un githuber en BD

  • List<Githuber> getGithubers() qui renvoie la liste des githubers présents en BD.

Dans un premier temps, tu peux définir "en dur" l'url JDBC de connexion à la BD en tant que variable static final dans le code de ton DAO.

N'oublie pas également, pour que ton code JDBC fonctionne au runtime, de rajouter la dépendance du driver JDBC mysql dans ton pom.xml

xml
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.17</version>
    </dependency>

Atention, depuis le connecteur MySQL8 ton url de connexion doit comporter un paramètre serverTimeZone!

Fais en sorte à présent que ton nouveau DAO soit injecté dans ton service GithuberService et utilise le:

  • dans la méthode track pour enregistrer un nouveau githuber en BD (sauf bien sûr s'il est déjà suivi ....)

  • dans la méthode getAllGithubers pour renvoyer la liste de tous les githubers suivis.

Au fait, que se passe-t-il dans ton appli si le handle saisi n'est pas un handle github valide? N'oublie pas que l'utilisateur se trompe parfois ....

↗
Simple JDBC DAO
dzone.com
↗
JDBC sample
tutorialspoint.com
↗
serverTimeZone configuration
stackoverflow.com

Supprimer un Githuber

Non ceci n'est pas le manuel du parfait serial killer ....

Maintenant que tu peux rajouter à l'envie de nouveaux githubers, il faut évidemment pouvoir également faire le ménage. C'est-à-dire pouvoir supprimer un githuber, ne plus le suivre.

Pour cela, implémente la méthode delete dans ton DAO (ainsi que la méthode untrack qui l'utilise dans ton GithuberService ). Que prend la méthode delete en paramètre? quelle en est sa signature?

Tu peux également rajouter un bouton "untrack" accessible sur la liste des githubers ainsi que la servlet UntrackServlet qui va avec. N'oublie pas que la suppression d'un githuber doit rafraichir la liste des githubers ...

↗
Delete method
stackoverflow.com

Challenge

Délègue ta configuration JDBC à une DataSource

Ton appli tourne, tu peux à présent interagir avec la base, tout va bien, c'est super, sauf que:

  • Que se passe-t-il si tu souhaites définir une base de prod? une base de test? Que se passe-t-il si l'on décide demain de migrer la BD sur un autre serveur? Ton code ne te permet pas en l'état de gérer de multiples environnements d'exécution, car il est étroitement lié à la configuration de la base. (Et oui tu as fait le très mauvais choix d'utiliser une variable static pour l'url JDBC directement dans ta classe DAO ;) )
  • Que se passe-t-il si le nombre d'utilisateurs augmente de manière significative ?Ton appli va multiplier le nombre de connexions à la BD et va passer de plus en plus de temps dans la phase de récupération de ces connexions ... Tu risques même de saturer le nombre de connexions simultanées ...

Pour répondre à ces 2 problématiques, qui sont l'externalisation de la configuration ainsi que l'optimisation de l'accès aux connexions de la BD, tu vas, plutôt que d'utiliser une connexion en dur dans ton DAO, utiliser une DataSource JNDI définie au niveau de ton serveur d'applications et reposant sur un pool de connexions.

Pour ce faire:

  • crée tout d'abord un pool de connexions vers ta BD depuis la page d'admin de ton serveur d'application (par ex. localhost:4848 pour Payara)
  • définis ensuite toujours depuis la page d'admin de ton serveur la ressource JNDI pointant vers ce pool de connexions
  • mets à disposition de ton serveur d'application la librairie de ton driver Mysql
  • injecte la DataSource définie précédemment au niveau de ton serveur d'application dans ton DAO

Ton appli tourne comme précédemment mais elle utilise à présent une méthode d'accès aux connexions plus solide et plus "scalable".

Ressources

Critères de validation

  • Ton appli permet d'enregistrer de nouveaux githubers à suivre en BD
  • Le listing de ton appli est basé sur les données en BD
  • On peut également supprimer un githuber si on ne souhaite plus le suivre
  • Ton DAO repose sur une DataSource définie au niveau de ton serveur d'applications