1. Java EE Spring – Introduction
Guillaume Dufrêne – Lionel Seinturier
Université de Lille
Java EE Spring
JDK
Java EE
Introduction 2
Définition
Ensemble de spécifications, de concepts et d'API
pour le développement en Java
d'applications d'entreprise
J2EE Java EE
1.0 1.1 1.2 1.3 1.4 5 6 7
Sun Microsystems Oracle
•
1
9
9
6
•
1
9
9
7
•
1
9
9
9
•
2
0
0
1
•
2
0
0
3
•
2
0
0
6
•
2
0
0
9
•
2
0
1
3
•
2
0
1
7
Historique
Eclipse Foundation
•
2
0
1
9
•
2
0
2
0
•
2
0
2
3
Jakarta EE
8 9 10
Notions générales
Introduction 3
Client-serveur
Notions générales
Introduction 4
Architecture client-serveur 3 tiers – n tiers (couches)
Modèle d’organisation des applications
Traitement
Données
Présentation
• Les tiers peuvent être distribués sur un réseau et accessibles en mode client/serveur
2. Notions générales
Introduction 5 Lionel Seinturier
Serveur d'applications
Un serveur qui héberge des applications accessibles via le réseau
Le plus utilisé pour Jakarta EE
Apache Tomcat
• 1ère version : 1999
• en octobre mars 2023 : version 10.1.7
• open source
• code développé en Java
Spring
Introduction 6
Définition
“Spring is an application framework for the Java platform
”
Outils et de règles facilitant le développement d'applications
Principes généraux
Introduction 7
Principes généraux mis en oeuvre dans Spring
• Approche MVC
• Injection de dépendances
Les applications web (mais pas uniquement)
Un écosystème vaste de plus de 50 sous-projets
MVC
Introduction 8
Définition
Un schéma de structuration des applications en trois parties
• Modèle données à présenter à l'utilisateur
• Vue affichage des données, interactions avec l'utilisateur
• Contrôleur gestion des actions de l'utilisateur
https://www.freecodecamp.org/news/the-model-view-controller-pattern-mvc-architecture-and-frameworks-explained/
3. MVC et 3-tiers
Introduction 9 Lionel Seinturier
Traitement
Données
Services
Contrôleur
Présentation
Modèle Vue
Architecture type d'une application Spring
• contrôleur
• accède à des services
• traitements
• accès données SGBD
• construit un modèle
• crée une vue avec ce modèle
• souvent associée au pattern
DTO Data Transfert Object
Injection de dépendances
Introduction 10
Principe
Eviter de coder en dur les dépendances entre
• un service
• le code qui utilise ce service
Séparation
• interface de service
• implémentation du service
• utilisation du service
Injection de dépendances
Introduction 11
Sans injection de dépendances
interface GreeterItf {
String sayHello();
}
class GreeterImpl implements GreeterItf {
public String sayHello() {
return "Hello world!";
} }
class Client {
GreeterItf greeter = new GreeterImpl();
void run() {
var str = greeter.sayHello();
System.out.println(str);
} }
on code en dur la
dépendance entre un
service et son
utilisation
+ pb si plusieurs utilisations
Injection de dépendances
Introduction 12
Injection de dépendances
• découpler le service de son (ses) utilisation
• ce n'est plus le développeur qui créé le lien
• le framework (Spring) le fait
• utilisation d'annotations pour
• le service
• @Service
• le code qui utilise le service
• @Autowired
4. Injection de dépendances
Introduction 13
Sans injection de dépendances
interface GreeterItf {
String sayHello();
}
class GreeterImpl implements GreeterItf {
public String sayHello() {
return "Hello world!";
} }
class Client {
GreeterItf greeter = new GreeterImpl();
void run() {
var str = greeter.sayHello();
System.out.println(str);
} }
Injection de dépendances
Introduction 14
Avec injection de dépendances
interface GreeterItf {
String sayHello();
}
@Service
class GreeterImpl implements GreeterItf {
public String sayHello() {
return "Hello world!";
} }
class Client {
@Autowired
GreeterItf greeter;
void run() {
var str = greeter.sayHello();
System.out.println(str);
} }
Spring positionne automatiquement
la valeur de greeter avec la référence de
l'objet GreeterImpl
on dit que Spring "injecte" la référence
Java EE Spring – HTTP > servlet > contrôleur
Guillaume Dufrêne – Lionel Seinturier
Université de Lille
Java EE Spring
HTTP
Guillaume Dufrêne – Lionel Seinturier
Université de Lille
HTTP
5. HTTP 17 Lionel Seinturier
HTTP
Hypertext Transfer Protocol (HTTP)
• protocole dit de niveau applicatif
• utilise TCP
ð garantie d'un transport fiable (sans erreur)
• pas de notion de connexion HTTP
• tous les commandes HTTP sont émises en mode texte (ASCII)
ð protocole simple, facilement implantable
• standardisé par une RFC
• existe depuis 1989 (v0.9)
• version 2 en 2015
• version 3 en 2022 (transport QUIC à la place de HTTP)
• cohabitation versions actuelles HTTP/2 et HTTP/3
HTTP 18 Lionel Seinturier
HTTP
2 messages (commandes) principaux
GET demande d'un document
POST envoi des données saisies dans un formulaire
Autres messages
• PUT dépôt (upload) d'un fichier sur le serveur
• DELETE suppression d'un fichier
• et aussi HEAD, OPTIONS, TRACE, PATCH, CONNECT
HTTP 19 Lionel Seinturier
HTTP
Requête
commande URL version_HTTP_comprise_par_le_client
en-tête_1_HTTP: valeur
....
en-tête_n_HTTP: valeur
informations envoyées par le client (par ex. texte saisi dans un formulaire HTML)
GET /index.html HTTP/2.0
Accept-language: fr
User-Agent: Mozilla/42.0
If-modified-since: Tue, 23 Jul 2020 10:24:05
POST /index.php HTTP/2.0
Accept-language: fr
nom=Seinturier&prenom=Lionel
HTTP 20 Lionel Seinturier
HTTP
Réponse
version_HTTP_du_serveur code_retour commentaire
en-tête_1_HTTP: valeur
....
en-tête_n_HTTP: valeur
document texte (HTML, …) ou binaire (GIF, JPG, …)
HTTP/2.0 200 OK
Content-Length: 9872
Content-Type: text/html
<HTML>
....
</HTML>
6. HTTP 21 Lionel Seinturier
HTTP
Réponse
code retour : renseigne sur le succès (200) ou l'échec (4xx) de la requête
• 200 : ok
• 404 : document inconnu
• 401 : authentification nécessaire
• 500 : erreur du serveur HTTP dans le traitement requête (servlet, PHP, …)
• 503 : serveur temporairement surchargé
• …
en-têtes HTTP : informations transmises par le serveur sur le document envoyé
• Content-Length : taille du document
• Last-Modified : date de dernière modification du document
• Server : nom du logiciel serveur
• Expire : date d'expiration du document
• Content-Type : type (MIME) du document
• … nombreux autres en-têtes possibles
REST
Java EE 22 Lionel Seinturier
Principe
• à la base HTTP requête-réponse pour le transfert de documents (HTML, etc.)
• REST
• HTTP comme moyen d'invoquer des services à distance
• on parle de ressources distantes
• chaque ressource = une URL
• ex. http://foo.com/myapp/users/Bob
• invocation d'un service
• une requête HTTP (GET, POST, PUT, DELETE, etc.)
• la réponse à une invocation de service
• le retour de la requête HTTP (souvent JSON, mais aussi …)
REST
Java EE 23 Lionel Seinturier
Pattern CRUD
• il n'y a pas de signification prédéfinie pour les requêtes GET, POST, PUT, DELETE, etc.
• laissée au choix du développeur
• souvent CRUD
• POST (C) create création
• GET (R) read lecture
• PUT (U) update mise à jour
• DELETE (D) delete suppression
Servlet
Guillaume Dufrêne – Lionel Seinturier
Université de Lille
Servlet
7. Page web dynamique côté serveur
Servlet 25
Servlet
Programme Java s'exécutant côté serveur Web
• permet de créer des pages web dynamiques
• exécuté par un "moteur" de servlet
• désigné par une URL ex. : http://www.fun.fr/myapp/prog
Ma première servlet
Servlet 26
Programmation
Ecriture d’une classe Java
• étend la classe HttpServlet
• redéfinit la méthode doGet
Ma première servlet
Servlet 27
Programmation
@WebServlet(urlPatterns={"/maservlet"})
public class HelloServlet extends HttpServlet {
public void doGet(
HttpServletRequest request,
HttpServletResponse response )
throws ServletException, IOException {
response.setContentType( "text/html" );
PrintWriter out = response.getWriter();
out.println( "<html><body>" );
out.println( "<h1>Bonjour</h1>" );
out.println( "</body></html>" );
}
}
Ma première servlet
Servlet 28
Résultat
Chargement dans un navigateur de l’URL http://.../maservlet
8. Instanciation et exécution
Servlet 29
Servlet
Chaque servlet est un objet Java
singleton
• 1 seule instance
• variables d’instance conservées
multi-threadé
• exécution concurrente, 1 thread par requête
• Conséquences :
ü protéger les variables
ü préférer les servlets stateless
Formulaires
Servlet 30
Récupération des données d'un formulaire
Exemple de formulaire
<HTML> <BODY>
<FORM ACTION="salutations"
METHOD=POST>
Nom <INPUT NAME="nom"> <P>
Prénom <INPUT NAME="prenom"> <P>
<INPUT TYPE=SUBMIT VALUE="Envoi">
</FORM>
</BODY> </HTML>
Formulaires
Servlet 31
Récupération des données d'un formulaire
String getParameter(String)
ð retourne le texte saisi
ð ou null si le nom de paramètre n'existe pas
Formulaires
Servlet 32
@WebServlet(urlPatterns={"/salutations"})
public class SalutationsServlet extends HttpServlet {
public void doPost(
HttpServletRequest request,
HttpServletResponse response )
throws ServletException, IOException {
response.setContentType( "text/html" );
PrintWriter out = response.getWriter();
String nom = request.getParameter( "nom" );
String prenom = request.getParameter( "prenom" );
out.println( "<html><body>" );
out.println( "<h1>Exemple de résultat</h1>" );
out.println( "Bonjour " + prenom + " " + nom );
out.println( "</body></html>" );
}
}
Récupération des données d'un formulaire
9. Formulaires
Servlet 33
Récupération des données d'un formulaire
clic
HTTP
Servlet 34
Servlet
public class CompteurServlet extends HttpServlet {
public void doGet( HttpServletRequest req, HttpServletResponse resp )
throws ServletException, IOException {
// ... le traitement lorsque la servlet est invoquée avec GET
}
public void doPost( HttpServletRequest req, HttpServletResponse resp )
throws ServletException, IOException {
// ... le traitement lorsque la servlet est invoquée avec POST
}
// ... éventuellement autres méthodes doXXX
}
Cycle de vie
Servlet 35
Servlet
une servlet = une classe Java
1. Instanciation (constructeur)
2. Exécution de la méthode init
3. Exécution multi-threadée des requêtes
4. Exécution de la méthode destroy
Possibilité de surcharger les méthodes init et destroy
void init(ServletConfig conf) throws ServletException { ... }
void destroy() { ... }
Session
Servlet 36
Définition
• suivre l'activité d'un utilisateur
• isoler les activités des utilisateurs simultanés
• chaque utilisateur a sa session qui lui est propre
• existe dans d'autres langages que Java (ex. PHP)
• débute à l’initiative du serveur
• se termine au bout d'un délai d'inactivité
• gérée à l'aide de cookies
• fonctionne comme une Map
void setAttribute( String name, Object value )
Object getAttribute( String name )
void setMaxIntervalTime( int seconds )
10. Session
Servlet 37
Programmation
@WebServlet(urlPatterns={"/maservlet"})
public class HelloServlet extends HttpServlet {
public void doGet(
HttpServletRequest request,
HttpServletResponse response )
throws ServletException, IOException {
HttpSession session = request.getSession();
Panier panier = (Panier) session.getAttribute("monpanier");
if( panier == null ) {
panier = new Panier();
session.setAttribute("monpanier",panier);
}
}
}
En résumé
Servlet
Servlet
• programme Java
• s'exécutant côté serveur Web
• que l'on peut invoquer à l'aide d'une URL
• générant du code HTML
• bien adapté à l'écriture de traitement
• contenant majoritairement du code Java
• et quelques parties de code HTML
Contrôleur
Guillaume Dufrêne – Lionel Seinturier
Université de Lille
Contrôleur
Contrôleur
Contrôleur 40
Définition
Une classe/objet
• qui reçoit des requêtes
• et qui fournit une réponse destinée à être affichée par une vue
• nombreuses solutions pour les vues (HTML, JSON, etc.)
Architecture
générale
Spring
11. Contrôleur
Contrôleur 41
Un premier exemple
@Controller
public class HelloController {
@GetMapping("/hello")
@ResponseBody
public String sayHello() {
return "<h1>Hello world!</h1>";
}
}
Contrôleur
Contrôleur 42
Un contrôleur retourne
• une chaîne de caractères contenant du HTML
• mais surtout le plus souvent
• (le nom d') une vue
• des données formattées en JSON
• etc.
Vue
Vue 43
Définition
• Partie présentation des applications Spring
• 2 solutions
• des vues gérées par des frameworks front
• Angular, React, Vue.js, etc.
• (hors de l'objectif de ce cours)
• des vues préparées côté serveur
• HTML, Thymeleaf, JSP, JSTL, etc.
CONTROLLEUR VUE
requête modèle
Vue
Vue 44
Contrôleur
• retourner le nom de la vue
• la vue peut être une "simple" page HTML
@Controller
public class HelloController {
@GetMapping("/hello")
public String sayHello() {
return "hello";
}
}
Fichier hello.html
<html>
<body>
<h1>Hello world!</h1>
</body>
</html>
12. Modèle
Vue 45 Lionel Seinturier
Modèle
• les données à transmettre à la vue
• utilisation de l'API org.springframework.ui.Model
• fonctionne comme une Map
Model addAttribute( String name, Object value )
Object getAttribute( String name )
boolean containsAttribute( String name )
Modèle
Vue 46
Modèle
• paramètre dans les arguments de la méthode
• sa valeur est injectée par Spring
• le modèle est transmis à la vue
@Controller
public class HelloController {
@GetMapping("/hello2")
public String sayHello( Model model ) {
model.addAttribute("nom","Doe");
model.addAttribute("prenom","John");
return "home";
}
}
Vue Thymeleaf
Java EE 47 Lionel Seinturier
Vue Thymeleaf
• un moteur de template HTML pour des vues construites côté serveur
• accès aux variables du modèle
<html xmlns:th="http://www.thymeleaf.org">
<body>
<h1>Hello
<span th:text="${prenom}"/>
<span th:text="${nom}"/>
</h1>
</body>
</html>
Contrôleur
Java EE 48 Lionel Seinturier
Les routes
• mécanisme pour aiguiller les requêtes vers les contrôleurs/méthodes
• cf. annotation @GetMapping
• autre annotation @RequestMapping
@Controller
@RequestMapping("/myapp")
public class HelloController {
@GetMapping("/hello")
public String sayHello() {
return "hello";
}
}
Accès
http://localhost:8080/myapp/hello
13. Contrôleur
Java EE 49 Lionel Seinturier
Les variables dans les routes
• mécanisme pour paramétrer les routes
• { … } dans l'URL
• accès à la valeur via une variable associée à l'annotation @PathVariable
@Controller
@RequestMapping("/ecommerce")
public class ArticleController {
@GetMapping("/article/{id}")
public String getArticle( @PathVariable String id ) { ... }
}
Accès
http://localhost:8080/ecommerce/article/smartphone
http://localhost:8080/ecommerce/article/tv
http://localhost:8080/ecommerce/article/170482365
...
Contrôleur
Java EE 50 Lionel Seinturier
Les variables dans les routes
• plusieurs variables peuvent être utilisées dans les routes
@Controller
@RequestMapping("/ecommerce")
public class CommandeController {
@GetMapping("/commande/{annee}/{mois}")
public List<Commande> findCommandeByAnneeAndMois(
@PathVariable String annee,
@PathVariable String mois )
{ ... }
}
Accès
http://localhost:8080/ecommerce/commande/2024/janvier
http://localhost:8080/ecommerce/commande/2020/mars
...
Contrôleur
Java EE 51 Lionel Seinturier
Différentes requêtes HTTP dans un contrôleur
• un même contrôleur peut gérer différentes requêtes HTTP (GET, POST, etc.)
• annotation @PostMapping, etc.
@Controller
@RequestMapping("/user")
public class UserController {
@PostMapping("/create")
public String create(
@RequestParameter String nom,
@RequestParameter String prenom )
{ ... }
@GetMapping("/read/{id}")
public String read( ... ) { ... }
}
<html> <body>
<form action="/user/create"
method="POST">
Nom <input name="nom">
Prénom <input name="prenom">
<input type="SUBMIT">
</form></body> </html>
Contrôleur REST
Contrôleur 52
Pattern REST + retours JSON
@RestController
public class ClientRestController {
@PostMapping(value="/client")
public Client create( @RequestBody Client client ) {
return service.create(client); }
@GetMapping("/client/{id}")
public Client read( @PathVariable long id ) {
return service.read(id); }
@PutMapping("/client/{id}")
public Client update( @PathVariable long id, @RequestBody Client client ) {
return service.update(id,client); }
@DeleteMapping("/client/{id}")
public void delete( @PathVariable long id ) {
service.delete(id); } }
14. Contrôleur
Contrôleur 53
Accès à la session
• paramètre HttpSession dans les arguments de la méthode
• sa valeur est injectée par Spring
@Controller
@RequestMapping("ecommerce")
public class MagasinController {
@GetMapping("/ajouter/{id}")
public String ajouter( HttpSession session, @PathVariable String id ) {
Panier monPannier = (Panier) session.getAttribute("panier");
if( monPannier == null ) {
monPannier = new Pannier();
session.setAttribute("panier", monPannier);
}
monPannier.ajouter(id);
} }
En résumé
Contrôleur 54
Contrôleur
• une classe annotée
• qui définit des méthodes
• pour recevoir des requêtes HTTP
• les traiter
• renvoyer un contenu
• HTML
• JSON
• etc.
Java EE Spring – Vues avec Thymeleaf
Lionel Seinturier
Université de Lille
Java EE Spring
Thymeleaf
Java EE 56 Lionel Seinturier
Thymeleaf
• un moteur de template HTML pour des vues construites côté serveur
• des parties fixes (HTML pur)
• des parties variables
• un namespace (ici associé au prefix th)
• avec des variables ${ ... }
<html xmlns:th="http://www.thymeleaf.org">
<body>
<h1>Hello
<span th:text="${prenom}"/>
<span th:text="${nom}"/>
</h1>
</body>
</html>
15. Thymeleaf
Java EE 57 Lionel Seinturier
Variables
• tous les types sont possibles (String, List, objets Java, etc.)
• pour les chaînes de caractères
• concaténation avec +
• chaînes de caractètres constantes '…….'
<html xmlns:th="http://www.thymeleaf.org">
<body>
<h1 th:text="'Hello '+${prenom}+' '+${nom}" />
</body>
</html>
Thymeleaf
Java EE 58 Lionel Seinturier
Variables
• pour les objets Java accès au variable ${objet.champ}
public class Personne {
private String nom;
private int age;
// + constructeurs, getters et setters pour nom et age
}
<html xmlns:th="http://www.thymeleaf.org">
<body>
<h1 th:text="${personne.nom}+' a '+${personne.age}+' ans'" />
</body>
</html>
• variable prédéfinie session
<h1 th:text="${session.email}" />
Thymeleaf
Vue 59
Itération
• balise each pour itérer sur les éléments d'une collection
• ici collection ${auteurs}
<html xmlns:th="https://www.thymeleaf.org" >
<body>
<h1>Liste des auteurs</h1>
<table border="1">
<tr><th>Id</th><th>Nom</th><th>Prénom</th></tr>
<tr th:each="auteur : ${auteurs}">
<td th:text="${auteur.id}" />
<td th:text="${auteur.nom}" />
<td th:text="${auteur.prenom}" />
</tr>
</table>
</body>
</html>
Thymeleaf
Java EE 60 Lionel Seinturier
Itération
• transmission de la collection dans le modèle
@Controller
@RequestMapping("/bib")
public class BibliothequeController {
@GetMapping("/home")
public String home( Model model ) {
List<Auteur> auteurs = new ArrayList<>();
auteurs.add( new Auteur("Hugo","Victor") );
auteurs.add( new Auteur("Zola","Emile") );
model.addAttribute("auteurs",auteurs);
return "home";
}
}
16. Thymeleaf
Vue 61 Lionel Seinturier
Itération
Résultat
Thymeleaf
Vue 62 Lionel Seinturier
Conditionnel
• balise if : action si la condition est vraie
• balise unless : idem faux
<td>
<span th:if="${personne.age >= 18}">Majeur</span>
<span th:unless="${personne.age >= 18}">Mineur</span>
</td>
• balises switch et case pour tester différents cas
Thymeleaf
Java EE 63 Lionel Seinturier
Thymeleaf
• un moteur de template HTML pour des vues construites côté serveur
• le moteur de template "officiel" de Spring
• permet de manipuler des variables
• itérations, conditionnels
• plus d'informations https://www.thymeleaf.org
Java Persistence API
Guillaume Dufrêne – Lionel Seinturier
Université de Lille
JPA
17. Java Persistence API
JPA 65
Définition
Java Persistence API
interface de programmation pour la gestion de données relationnelles
appelé Jakarta Persistance depuis la version 3.0 en 2020
• Manipulation de données et de leurs relations
• 3 parties
• les annotations
• l'API pour manipuler les données
• JPQL
JPA et ORM
JPA 66
Définition
Object Relation Mapping
Technique de programmation
Schéma de données Objets
ORM
• opérations SQL courantes
• vision homogène
• haut niveau
• transfert automatique des données
ORM
Vocabulaire JPA
JPA 67
Définitions
Entité
• un ensemble de données d'un même type (eg. Personne)
Persistance / persister
• action de sauvegarder des données dans une base de données (SGBD)
JPA et SGBD
JPA 68
Principes de mise en correspondance
• une classe Java une table SQL
• une propriété d'une classe une colonne dans une table SQL
• une référence entre classes une relation entre tables SQL
• un objet Java un enregistrement dans une table SQL
Remarques
• nb objets ≠ nb enregistrements
• les données peuvent être chargées de façon dite paresseuse (lazy)
18. Annotation @Entity
JPA 69
Entité
• à déclarer sur les classes dont les données doivent être prises en charge par JPA
@Entity
public class Personne {
private String nom;
private int age;
public Personne( String nom, int age ) {
this.nom = nom;
this.age = age;
}
public String getNom() { return nom; }
public void setNom( String nom ) { this.nom = nom; }
public int getAge() { return age; }
public void setAge( int age ) { this.age = age; }
}
Annotations @Id et @GeneratedValue
JPA 70
Entité
@Id : clé primaire
@GeneratedValue : générer automatiquement la clé
@Entity
public class Personne {
private long id;
private String nom;
private int age;
public Personne( String nom, int age ) {
this.nom = nom;
this.age = age;
}
@Id
@GeneratedValue
public long getId() { return id; }
public void setId( long id ) { this.id = id; }
// méthodes getNom, setNom, getAge, setAge
}
Repository
JPA 71 Lionel Seinturier
Repositoy
• un composant pour gérer les instances d'une entité
• fournit des méthodes pour accéder et sauvegarder les instances de l'entité
• traduit ces méthodes en requêtes SQL exécutées par la base de données
• CRUDRepository : un repository qui fournit les 4 opérations CRUD
• un type générique avec 2 paramètres : l'entité et la clé de l'entité
import org.springframework.data.repository.CrudRepository;
public interface PersonneRepository
extends CrudRepository<Personne, Long> {}
Rq : Repository spécifique à JPA avec Spring
si JPA sans Spring, il existe un autre composant : EntityManager
CRUD Repository
JPA 72 Lionel Seinturier
Méthodes définies par CrudRepository
Accès au repository par injection de dépendances
@Autowired
private PersonneRepository repo;
Création d'une entité
Personne bob = new Personne("Bob",42);
repo.save(bob);
// requête SQL executée : INSERT INTO PERSONNE VALUES (1,'Bob',42)
19. CRUD Repository
JPA 73 Lionel Seinturier
Méthodes définies par CrudRepository
Accès à une entité à partir de sa clé primaire
Personne bob = repo.findById(1);
// requête SQL exécutée : SELECT * FROM PERSONNE WHERE ID=1
Modificiation d'une entité
bob.setAge( bob.getAge() + 1 );
repo.save(bob);
// requête SQL exécutée : UPDATE PERSONNE SET AGE=43 WHERE ID=1
Supprésion d'une entité
repo.delete(bob);
// requête SQL exécutée : DELETE FROM PERSONNE WHERE ID=1
CRUD Repository
JPA 74
Repository étendu
• définition de requêtes propres au domaine de l'Entity
• convention de nommage pour les méthodes
• findBy attribut
public interface PersonneRepository
extends CrudRepository<Personne, Long> {
List<Personne> findByNom( String nom );
List<Personne> findByNomAndAge( String nom, int age );
List<Personne> findByNomIgnoreCase( String nom );
List<Personne> findByNomOrderByAgeAsc( String nom );
List<Personne> findByNomOrderByAgeDesc( String nom );
}
And, Or,
LessThan,
GreaterThan
Like, Between
Relations entre entités
JPA 75
Relations entre entités
Liens entre des types de données
Cardinalités
• 1-n
• n-1
• 1-1
• n-n
Annotation JPA
• @OneToMany
• @ManyToOne
• @OneToOne
• @ManyToMany
Relations entre entités
JPA 76
Exemple
@Entity
public class Ecrivain {
@Id long id;
String nom;
@OneToMany
List<Livre> oeuvres;
// constructeur
// getters/setters
}
@Entity
public class Livre {
@Id long id;
String titre;
int annee;
@ManyToOne
Ecrivain auteur;
// constructeur
// getters/setters
}
Ecrivain Livre
1 *
20. Relations entre entités
JPA 77 Lionel Seinturier
Traduction en schéma relationnel
• 3 tables
• 1 pour chaque entité
• 1 pour la relation
• table ECRIVAIN
• 1 colonne pour ID et 1 colonne pour NOM
• table LIVRE
• 1 colonne pour ID, 1 colonne pour TITRE et 1 colonne pour ANNEE
• 1 colonne supplémentaire AUTEUR_ID comme clé étrangère
• table ECRIVAIN_OEUVRES pour la relation
• 1 colonne ECRIVAIN_ID
• 1 colonne OEUVRES_ID
Relations entre entités
JPA 78 Lionel Seinturier
Notion de mise à jour en cascade
Problématique
• si un côté de la relation est mis à jour, il faut propager la mise à jour de l'autre côté
• exemple
• ajout d'un livre
• => il faut mettre à jour la liste des oeuvres de l'auteur
• la notion de cascade permet de propager les mises à jour
@Entity
public class Ecrivain {
@Id long id;
String nom;
@OneToMany
(cascade=CascadeType.ALL)
List<Livre> oeuvres;
@Entity
public class Livre {
@Id long id;
String titre;
int annee;
@ManyToOne
(cascade=CascadeType.ALL)
Ecrivain auteur;
Relations entre entités
JPA 79 Lionel Seinturier
Types de cascade (CascadeType)
• PERSIST : creation d'une entité
• MERGE : mise à jour d'une entité
• REMOVE : suppression d'une entité
• ALL : toutes les opérations
Modèle de données existant
JPA 80
Principe
• Correspondance attributs et colonnes
• Annotations @Table et @Column
@Entity
@Table(name="AUTEURS")
public class Ecrivain {
@Column("NOM_ID")
String nom;
@OneToMany
List<Livre> oeuvres;
// bean
}
@Entity
@Table(name="OUVRAGES")
public class Livre {
@Column("TITRE_ID")
String titre;
int annee;
@ManyToOne
Ecrivain auteur;
// bean
}
21. CRUD Repository
JPA 81
Requêtes spécifiques
public interface EcrivainRepository extends CrudRepository<Ecrivain, Long> {
@Query("SELECT DISTINCT a
FROM Ecrivain e INNER JOIN e.oeuvres l
WHERE l.annee = :annee")
public List<Ecrivain> findByAnnee( @Param("annee") int annee );
}
CRUD Repository
JPA 82
Data Transfert Object
• un pattern pour transférer des données entre des couches
• on ne transfère que les données nécessaires
public class NomPrenomDTO {
private String nom;
private String prenom;
public NomPrenomDTO(String nom, String prenom) { ... }
// getters, setters
}
public interface AuteurRepository extends CrudRepository<Auteur, Long> {
@Query("SELECT DISTINCT new NomPrenomDTO(a.nom,a.prenom)
FROM Auteur a INNER JOIN a.livres l
WHERE l.annee=:annee")
public List<NomPrenomDTO> findByAnnee( @Param("annee") int annee );
}
Transaction
JPA 83
Définition
Groupe de requêtes devant être exécutées de façon indivisible
Objectifs
• Concurence des traitements et Consistance des données
Opérations
• début de transaction (begin)
• engagement de la transaction (commit)
• annulation de la transaction (rollback)
Transaction
JPA 84
Exemple (1/3)
Transfert d'argent entre deux comptes bancaires
Contraintes
1. le solde d'un compte ne peut être négatif
2. des transferts (lectures et écritures du solde) simultanés ne doivent pas
mener à des incohérences
=> les transferts simultanés doivent mener au même résultat
que s'ils avaient été exécutés en séquence
22. Définition de contraintes
JPA 85
Entité
@Entity
public class Account {
@Id
@GeneratedValue
public long id;
public String owner;
@Column(columnDefinition = "FLOAT CHECK( amount >= 0 )")
public double amount;
// ...
Transaction
JPA 86
Exemple (2/3)
Soit une entité Compte avec un attribut solde
@Transactional
public void transfert( Accounf bob, Account anne, double montant ) {
anne.setSolde( anne.getSolde() + montant );
bob.setSolde( bob.getSolde() - montant );
}
Contrainte #1 (le solde ne peut pas être négatif)
• si au départ bob.solde = 42
• => il faut annuler la transaction
Transaction
JPA 87
Exemple (3/3)
Contrainte #2 (pas d'incohérence en cas de parallélisme)
• 2 transferts simultanés de 100, au départ anne.solde=42 et bob.solde=200
• t1 anne.getSolde -> t1 anne.setSolde -> t1 bob.getSolde -> t1 bob.setSolde
• t2 anne.getSolde -> t2 anne.setSolde -> t2 bob.getSolde -> t2 bob.setSolde
• si enchaînement
• t1 anne.getSolde 42 anne.solde=42, bob.solde=200
• t2 anne.getSolde 42 anne.solde=42, bob.solde=200
• t1 anne.setSolde anne.solde=142, bob.solde=200
• t2 anne.setSolde anne.solde=142, bob.solde=200 bug !!
• => la transaction permet d'éviter ce cas
JPA & Hiérarchie de classes
JPA 88
Principe
• par défaut : 1 classe = 1 table
• POO : héritage de classes
Problématique
• lien hiérarchie classes
tables SGBD ?
23. JPA & Hiérarchie de classes
JPA 89
Solutions
3 politiques proposées par JPA
• SINGLE_TABLE
• une seule table
• colonne discrimante
• TABLE_PER_CLASS
• une table par classe
• données héritées dans toutes les tables
• JOINED
• une table par classe
• chaque table ne contient que les données propres à la classe
JPA & Hiérarchie de classes
JPA 90
Avantages / inconvénients
• SINGLE_TABLE
+ vision globale
- espace inutilisé des entités intermédiaires
• TABLE_PER_CLASS
+ simple, intuitif
- perte du couplage avec les entités héritées
• JOINED
+ plus proche de la hiérarchie de classe
- navigation entre tables pour recontituer les données d'une entité
En résumé
JPA 91
Java Persistence API
• Interface de programmation pour la gestion de données relationnelles
• Manipulation des données d'un SGBD comme des objets
• Sauvegarde des informations transparentes
• Abstraction de SQL