0% ont trouvé ce document utile (0 vote)
3 vues24 pages

TP Springdata

Ce TP vise à initier les utilisateurs à Spring Boot et JPA en développant une application de gestion de tâches. L'application permet de classer les tâches selon leur état et utilise une base de données H2 en mode embarqué. Les concepts clés incluent la modélisation des entités, l'utilisation de JDBC et JPA pour interagir avec la base de données, et la création d'une interface utilisateur pour gérer les tâches.

Transféré par

ndayakevin2007
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
3 vues24 pages

TP Springdata

Ce TP vise à initier les utilisateurs à Spring Boot et JPA en développant une application de gestion de tâches. L'application permet de classer les tâches selon leur état et utilise une base de données H2 en mode embarqué. Les concepts clés incluent la modélisation des entités, l'utilisation de JDBC et JPA pour interagir avec la base de données, et la création d'une interface utilisateur pour gérer les tâches.

Transféré par

ndayakevin2007
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

TP : Spring Data JPA

1.1. Objectif
L’objectif de ce TP est de vous initier à Spring Boot en utilisant Java Persistence API (JPA).
Vous serez amené à développer une application permettant à un utilisateur de gérer ses tâches, en
les classant selon leur état : « à faire », « en cours » et « terminé ».

L'environnement de développement est le suivant :


• Java : Java SE 17 ou 21
• Gradle 8.5+ ou Gradlew
• SpringBoot 4
Ce TP utilise les documentations officielles de Spring Boot suivantes :
• [Link]
• [Link]
• [Link]
• [Link]
• [Link]
Dans ce TP, l’objectif n’est pas d’utiliser une base de données non relationnelle, ni de mettre en
place une architecture REST à ce stade.

1.2. Quelques concepts


Grâce à Spring Data, le framework Spring permet d’interagir avec différents types de bases de
données. Toutefois, dans ce TP, nous nous limiterons aux bases de données relationnelles.
Ces bases peuvent être manipulées à plusieurs niveaux d’abstraction : depuis une approche proche
du SGBD (via JDBC et ses connecteurs) jusqu’à une abstraction complète grâce à un ORM
(Object-Relational Mapping), en l’occurrence JPA.

Java
ORM
JDBC
Base de données
Spring est compatible avec de nombreux systèmes de gestion de bases de données relationnelles tels
que Oracle, MySQL/MariaDB, PostgreSQL, Derby (JavaDB) ou encore H2.
Dans le cadre de ce TP, nous utiliserons la base H2 (développée en Java), configurée en mode
embarqué (embedded, sans serveur) et en mode fichier (et non in-memory).
À noter qu’il aurait également été possible d’utiliser Derby, qui est directement fourni avec le JDK.

1.3. Modélisation et SQL


Dans cette application, nous allons manipuler des tâches (post-it ou notes), organisées par
catégories.
Chaque tâche est caractérisée par :
• un contenu,
• une catégorie,
• une date de création,
• une date d’échéance (date à laquelle la tâche doit être réalisée).
Une catégorie, quant à elle, est simplement définie par un nom.
Ci-dessous, le code SQL permettant de créer les tables tasks et categories. Ce script est adapté au
SGBD H2, notamment en ce qui concerne les types de données et les fonctions disponibles. H2
prenant en charge les clés étrangères, nous en tirerons pleinement parti.
DROP TABLE tasks IF EXISTS;
DROP TABLE categories IF EXISTS;

CREATE TABLE categories (


category_id IDENTITY PRIMARY KEY,
name VARCHAR(20) DEFAULT ''
);
INSERT INTO categories(name) values('todo');
INSERT INTO categories(name) values('wip');
INSERT INTO categories(name) values('done');

CREATE TABLE tasks (


task_id IDENTITY PRIMARY KEY,
category INTEGER NOT NULL,
content VARCHAR(500) NOT NULL,
creation_date DATE DEFAULT CURRENT_DATE(),
end_date DATE DEFAULT NULL,
FOREIGN KEY(category) REFERENCES categories(category_id)
);

INSERT INTO tasks (category, content) values(3, 'finir le tp 1');


INSERT INTO tasks (category, content) values(2, 'finir le tp 2');
INSERT INTO tasks (category, content) values(1, 'finir le tp 3');
1.4. Mise en place du projet
Pour ce TP, il est nécessaire de créer un nouveau projet Spring Boot en configurant les paramètres

⚙️
suivants :

Configuration du projet
• Project : Gradle (Groovy) – outil d’automatisation de build
• Langage : Java

📦
• Version de Spring Boot : 4.0.1 (ou toute version stable récente)

Dépendances à inclure
• Spring Boot DevTools
• Spring Web (pour le développement d’une application web)
• Thymeleaf
• Lombok
• H2 Database
• JDBC API
• Spring Data JPA

🏷️
• Spring Data JDBC

Métadonnées du projet
• Group : app
• Artifact : tasks
• Name : Tasks
• Package name : app
• Version de Java : 17

2. Manipuler une base avec JDBC


2.1. Création de la base
Nous allons développer une application principale capable d’initialiser la base de données (structure
et données). Pour cela, nous allons exploiter les arguments passés en ligne de commande en
implémentant l’interface CommandLineRunner.
Voici un exemple de classe principale :
package app;

import [Link];
import [Link];
import [Link];

import [Link];
import [Link];

import [Link];
import [Link];
import [Link];
import [Link];

@SpringBootApplication
public class TasksApplication implements CommandLineRunner {

private static final Logger log = [Link]([Link]);

@Autowired
JdbcTemplate jdbcTemplate;

public static void main(String[] args) {


[Link]([Link], args);
}

@Override
public void run(String... args) throws Exception {

List<String> list = [Link](args);

if ([Link]("install")) {
// Code de création de la base (structure + données)
}
}

🧩
}

Explications
Deux attributs principaux sont utilisés :
• log : permet d’afficher des informations sur l’exécution de l’application (alternative aux
sorties standards).
• jdbcTemplate : fourni automatiquement par Spring, il permet d’interagir directement avec
la base de données via JDBC.
Lors de l’exécution, si le paramètre install est présent, le script d’initialisation de la base sera
exécuté. Sinon, cette étape sera ignorée.

▶️ Exécution
Pour lancer l’application avec initialisation de la base :
gradle bootRun –args='install'

⚙️Configuration de la base de données


Il est indispensable de configurer la source de données dans le fichier [Link] :
[Link]-auto=none
[Link]=jdbc:h2:file:./toudou
📝 Remarques importantes
• Le paramètre [Link]-auto est spécifique à Hibernate :
• none : aucune génération automatique (si vous utilisez JDBC pour créer la base)
• update : mise à jour automatique du schéma par JPA/Hibernate
• Le script de création (DDL – Data Definition Language) doit être exécuté manuellement via
JdbcTemplate.
• Les fonctions SQL peuvent varier selon le SGBD (par exemple : CURRENT_DATE(),
NOW(), TODAY(), etc.).

2.2. Utilisation de la base avec JDBC


l est possible de vérifier que les tables ont bien été créées en adoptant une approche similaire, par
exemple en faisant réagir l’application à une commande test.
Dans ce cas, le programme peut exécuter une requête de lecture sur la table categories. Le code
suivant illustre comment récupérer les données à l’aide d’une lambda, puis les stocker dans une
liste :
List<String> categories;
String sql = "select * from categories";
categories = [Link](sql,
(rs, rowNum) ->
{ return new String ([Link]("name") );
}
);
[Link]([Link]());

Java
Le deuxième code permet de lire la table tasks
sql = "SELECT * FROM tasks";
List<Map<String, Object>> rows = [Link](sql);

for (Map row : rows) {


[Link]([Link]("content").toString());
[Link]([Link]((Integer)[Link]("category")-1));
}

Java

2.3. Console h2
Lorsque votre serveur est en cours d’exécution, une console H2 est accessible à l’adresse suivante :
[Link]
Connectez-vous à la console H2 sans renseigner de login ni de mot
de passe, en utilisant simplement l’URL de connexion définie dans
le fichier [Link].

2.4. Affichage web


À l'instar du TP précédent, vous pouvez créer une vue pour afficher les tâches à faire. Il suffit
d'ajouter la liste des choses à faire au modèle quand on écrit le contrôleur. Si on passe la liste avec
un modèle, cela va donner :
<h1>Choses à faire</h1>

<p th:if="${[Link]()}">Aucune tâche à afficher</p>

<table th:unless="${[Link]()}">
<tr th:each="row: ${rows}">
<td th:text="${[Link]('note_id')}"></td>
<td th:text="${[Link]('content')}"></td>
</tr>
</table>
HTML
On utilise la méthode get() car row est une Map

On va pas aller plus loin sur l'utilisation directe de JDBC.

3. Manipulation avec JPA (Hibernate)


lutôt que de manipuler directement des tables et des tuples, il est plus élégant de gérer des objets
appelés entités.
Pour cela :
• on crée une classe Java pour chaque table,
• et on explicite, si nécessaire, la correspondance (mapping) entre les attributs de la classe et
les colonnes de la table.
Spring Boot applique par défaut une configuration par convention, que vous pouvez modifier
avec des annotations si besoin.
Ainsi :
• chaque table correspond à une classe,
• chaque tuple correspond à un objet de cette classe.
Voici un exemple pour la classe Category :
package [Link];

import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

@Entity
@Table(name="categories")
public class Category {

@Id
@GeneratedValue(strategy=[Link])
@Column(name="category_id")
private Long id;
private String name;

protected Category() {}

public Category(String name) {


[Link] = name;
}

@Override
public String toString() {
return [Link](
"Category[id=%d, name='%s']", id, name);
}

// il va falloir mettre les getters/setters


// c'est hyper important pour le binding
// voir la note plus bas
}

🧩
Java

Explications
• @Entity : indique que la classe est une entité JPA et sera mappée à une table.
• @Id : définit la clé primaire.
• @GeneratedValue : configure la génération automatique de la valeur de la clé
primaire.
• Les attributs de la classe sont automatiquement mappés aux colonnes de la table (par
convention, le nom des colonnes correspond au nom des attributs).

Et celui de la classe Task :

package [Link];

import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

@Entity
public class Task {

@Id
@GeneratedValue(strategy = [Link])
private Long id;

private String content;

@ManyToOne
@JoinColumn(name = "category_id")
private Category category;

private LocalDate creationDate;

private LocalDate dueDate;

private String status; // "À faire", "En cours", "Terminé"

// Constructeurs
public Task() {}
public Task(String content, Category category, LocalDate creationDate, LocalDate dueDate,
String status) {
[Link] = content;
[Link] = category;
[Link] = creationDate;
[Link] = dueDate;
[Link] = status;
}

// Getters et setters
public Long getId() {
return id;
}

public void setId(Long id) {


[Link] = id;
}

public String getContent() {


return content;
}

public void setContent(String content) {


[Link] = content;
}

public Category getCategory() {


return category;
}

public void setCategory(Category category) {


[Link] = category;
}

public LocalDate getCreationDate() {


return creationDate;
}

public void setCreationDate(LocalDate creationDate) {


[Link] = creationDate;
}

public LocalDate getDueDate() {


return dueDate;
}
public void setDueDate(LocalDate dueDate) {
[Link] = dueDate;
}

public String getStatus() {


return status;
}

public void setStatus(String status) {


[Link] = status;
}
}
Java
Les clés primaires avec la génération automatique sont spécifiées @Id et @GeneratedValue, les
clés étrangères également (@JoinColumn et @ManyToOne. Si les noms de table ou de colonne
sont différents de la configuration par convention, un paramètre name vient corriger cela (@Table
et @Column.

Les getters et les setters n'ont pas été écrits. Vous pouvez :
• les écrire à la main
• les générer avec votre EDI
• utiliser le projet lombok pour bénéficier des annotations @Getter et @Setter sur les
attributs.
Si vous oubliez un setter par exemple, le binding ne vous permettra pas de mettre à jour l'objet mais
vous n'aurez aucune erreur.
Ces classes servent désormais à représenter des entités que Spring Data JPA pourra gérer
automatiquement via des repositories, qui jouent le rôle de DAO (Data Access Object) dans Spring
Boot.
Pour chaque entité, il faut créer un repository correspondant. On peut utiliser :
• CrudRepository : fournit les opérations CRUD de base (Create, Read, Update, Delete),
• JpaRepository (interface fille de CrudRepository) : ajoute des fonctionnalités avancées
comme la pagination et le tri.
package [Link];

import [Link];
import [Link];

public interface CategoryRepository extends JpaRepository<Category, Long> {


// Ici, on peut ajouter des méthodes de recherche spécifiques si nécessaire
}
Java
package [Link];

import [Link];
import [Link];
import [Link];

public interface TaskRepository extends JpaRepository<Task, Long> {


List<Task> findByStatus(String status); // Exemple de méthode personnalisée
}
Java

🧩 Explications
• Les repositories étendent JpaRepository : Spring Boot fournit automatiquement les
méthodes CRUD et la gestion des transactions.
• On peut définir des méthodes de recherche personnalisées simplement en suivant la
convention de nommage (findBy...).
• Cela supprime la nécessité d’écrire du SQL ou du JDBC pour la plupart des opérations
courantes.
Grâce à Spring Data JPA, il n’est pas nécessaire d’écrire une seule ligne d’implémentation
pour les méthodes CRUD ou les recherches simples.
Spring génère automatiquement le code nécessaire à l’exécution à partir des interfaces de
repository que vous avez définies.

Dans l’application, pour pouvoir utiliser un repository, il suffit de laisser Spring injecter
automatiquement l’instance correspondante :
// import [Link];
@Autowired
TaskRepository taskRepository;

🧩 Explications
• @Autowired permet à Spring de fournir automatiquement une instance
fonctionnelle de TaskRepository.
• Ce repository fournit toutes les méthodes nécessaires pour effectuer des
requêtes ou créer des objets dans la base.

Exemple d’ajout d’une tâche en base :

Task task = new Task(


[Link](1L).get(), // récupère la
catégorie avec l’ID 1
"essai en cours",
[Link](), // date de création
[Link]().plusDays(2), // date d’échéance
"En cours" // statut
);
[Link](task); // sauvegarde la tâche en base
Java
On va exploiter les requêtes dans la section suivante.

4. Interface utilisateur
Pour notre application, nous voulons proposer plusieurs pages et actions pour gérer les tâches :

URL Méthode HTTP Action


/ GET Lister toutes les tâches
/tasks GET Lister toutes les tâches
/tasks/new GET Afficher un formulaire pour créer une nouvelle tâche
/tasks POST Créer une nouvelle tâche

Et, pour être exhaustif, on pourrait également gérer :

URL Méthode HTTP Action


/tasks/{id} GET Afficher les détails d’une tâche spécifique
/tasks/{id}/edit GET Afficher un formulaire pour modifier la tâche
/tasks/{id} PATCH/PUT Mettre à jour la tâche donnée
/tasks/{id} DELETE Supprimer la tâche donnée

Les méthodes GET servent à afficher les informations ou les formulaires.


• Les méthodes POST, PUT/PATCH, et DELETE servent à créer, mettre à jour ou
supprimer des données.
• Ces routes pourront être gérées via un contrôleur Spring MVC et affichées avec des pages
Thymeleaf.

4.1. Affichage des tâches


Pour afficher les tâches dans l’application, il faut créer :
1. Un template Thymeleaf pour la page web,
2. Un contrôleur Spring MVC qui récupère les données et les envoie au template.
Exemple de contrôleur pour lister toutes les tâches :
package [Link];

import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

@Controller
public class TaskController {

@Autowired
private TaskRepository taskRepository;

@GetMapping("/tasks")
public String listTasks(Model model) {
[Link]("tasks", [Link]());
return "tasks"; // nom du template Thymeleaf [Link]
}
}

🧩
Java

Explications
• @Controller : indique que cette classe gère les requêtes web.
• @GetMapping("/tasks") : la méthode est appelée lorsqu’un utilisateur accède à /tasks.
• Model model : permet de transmettre des données au template.
• [Link]() : récupère toutes les tâches de la base.
• [Link]("tasks", …) : ajoute la liste des tâches au modèle, accessible dans le
template sous le nom tasks.
• Le template [Link] pourra ensuite parcourir la liste et afficher chaque tâche dans la page
web.
Voici un exemple complet de template Thymeleaf pour afficher la liste des tâches avec leur
contenu, catégorie, dates et statut :
<!DOCTYPE html>
<html xmlns:th="[Link]
<head>
<meta charset="UTF-8">
<title>Liste des tâches</title>
<link rel="stylesheet" href="/css/[Link]">
</head>
<body>
<h1>Liste des tâches</h1>

<a href="/tasks/new">Créer une nouvelle tâche</a>

<table border="1" cellpadding="5" cellspacing="0">


<thead>
<tr>
<th>ID</th>
<th>Contenu</th>
<th>Catégorie</th>
<th>Date de création</th>
<th>Date d'échéance</th>
<th>Statut</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr th:each="task : ${tasks}">
<td th:text="${[Link]}">1</td>
<td th:text="${[Link]}">Contenu</td>
<td th:text="${[Link]}">Catégorie</td>
<td th:text="${[Link]}">2026-01-01</td>
<td th:text="${[Link]}">2026-01-05</td>
<td th:text="${[Link]}">À faire</td>
<td>
<a th:href="@{'/tasks/' + ${[Link]} + '/edit'}">Modifier</a> |
<a th:href="@{'/tasks/' + ${[Link]} + '/delete'}">Supprimer</a>
</td>
</tr>
</tbody>
</table>
</body>
</html>

🧩
HTML

Explications
• th:each="task : ${tasks}" : parcourt la liste des tâches passée depuis le contrôleur.
• th:text="${…}" : insère dynamiquement les valeurs des propriétés de chaque tâche dans le
HTML.
• Les colonnes affichent : ID, contenu, catégorie, dates, statut.
• Les liens Modifier et Supprimer sont préparés pour pointer vers les routes correspondantes
(/tasks/{id}/edit et /tasks/{id}/delete).
• Un lien Créer une nouvelle tâche renvoie vers la page de création.
Ce template fonctionne directement avec le contrôleur que nous avons défini précédemment et
affichera toutes les tâches présentes dans la base.

4.2. Ajouter une tâche


Voici comment compléter le contrôleur pour sauvegarder une nouvelle tâche via la méthode
POST :
@PostMapping("/tasks")
public String createTask(@ModelAttribute("task") Task task) {
// Sauvegarde la tâche en base
[Link](task);
// Redirige vers la liste des tâches
return "redirect:/tasks";
}

🧩
Java

Explications
• @PostMapping("/tasks") : correspond à la route POST du formulaire de création.
• @ModelAttribute("task") : lie automatiquement les champs du formulaire à un objet
Task.
• [Link](task) : persiste l’objet Task en base, Spring Data JPA s’occupe de tout.
• return "redirect:/tasks" : après la création, l’utilisateur est redirigé vers la liste des tâches.
Avec cette méthode, le cycle complet est opérationnel :
1. L’utilisateur clique sur Créer une nouvelle tâche → formulaire /tasks/new.
2. Remplit les champs et soumet → POST /tasks.
3. Spring enregistre la tâche en base et redirige vers la liste des tâches.

package [Link];

import [Link];
import [Link];
import [Link].*;
import [Link];

import [Link];
import [Link];
import [Link];

import [Link];

@Controller
@RequestMapping("/tasks")
public class TaskController {

@Autowired
private TaskRepository taskRepository;

@Autowired
private CategoryRepository categoryRepository;

// Liste toutes les tâches


@GetMapping
public String listTasks(Model model) {
[Link]("tasks", [Link]());
return "tasks"; // template [Link]
}

// Formulaire pour créer une nouvelle tâche


@GetMapping("/new")
public String newTaskForm(Model model) {
[Link]("task", new Task());
[Link]("categories", [Link]());
return "task_form"; // template task_form.html
}
// Créer une nouvelle tâche
@PostMapping
public String createTask(@ModelAttribute("task") Task task) {
[Link](task);
return "redirect:/tasks";
}

// Formulaire pour modifier une tâche existante


@GetMapping("/{id}/edit")
public String editTaskForm(@PathVariable Long id, Model model) {
Optional<Task> taskOpt = [Link](id);
if ([Link]()) {
[Link]("task", [Link]());
[Link]("categories", [Link]());
return "task_form"; // on peut réutiliser le même template
} else {
return "redirect:/tasks";
}
}

// Modifier une tâche


@PostMapping("/{id}")
public String updateTask(@PathVariable Long id, @ModelAttribute("task") Task task) {
[Link](id); // s'assurer que l'ID est correct
[Link](task);
return "redirect:/tasks";
}

// Supprimer une tâche


@GetMapping("/{id}/delete")
public String deleteTask(@PathVariable Long id) {
[Link](id);
return "redirect:/tasks";
}

// Afficher les détails d'une tâche


@GetMapping("/{id}")
public String showTask(@PathVariable Long id, Model model) {
Optional<Task> taskOpt = [Link](id);
if ([Link]()) {
[Link]("task", [Link]());
return "task_detail"; // template task_detail.html à créer si nécessaire
} else {
return "redirect:/tasks";
}
}
}
Java

🧩 Explications
• @RequestMapping("/tasks") : préfixe commun pour toutes les routes liées aux tâches.
• listTasks() : affiche toutes les tâches.
• newTaskForm() / createTask() : gestion de la création d’une tâche.
• editTaskForm() / updateTask() : gestion de la modification d’une tâche existante.
• deleteTask() : supprime une tâche par son ID.
• showTask() : affiche les détails d’une tâche spécifique.
• Les formulaires de création et de modification peuvent réutiliser le même template
Thymeleaf (task_form.html).

Avec ce contrôleur et les templates précédemment créés, tu disposes d’une application complète
de gestion de tâches en Spring Boot avec JPA, CRUD complet et interface web.
Voici des exemples de templates Thymeleaf pour compléter l’interface :

1️⃣ Template pour modifier ou créer une tâche (réutilisation de


task_form.html)
Le même formulaire sert pour création et modification. Il suffit de vérifier si l’objet task a un ID
ou non.

<!DOCTYPE html>
<html xmlns:th="[Link]
<head>
<meta charset="UTF-8">
<title th:text="${[Link] == null} ? 'Créer une tâche' : 'Modifier la tâche'">Tâche</title>
</head>
<body>
<h1 th:text="${[Link] == null} ? 'Créer une tâche' : 'Modifier la tâche'"></h1>

<form th:action="@{${[Link] == null} ? '/tasks' : '/tasks/' + ${[Link]}}" th:object="${task}"


method="post">
<div>
<label for="content">Contenu :</label>
<input type="text" id="content" th:field="*{content}" required>
</div>

<div>
<label for="category">Catégorie :</label>
<select id="category" th:field="*{category}" required>
<option th:each="cat : ${categories}" th:value="${cat}"
th:text="${[Link]}"></option>
</select>
</div>

<div>
<label for="dueDate">Date d'échéance :</label>
<input type="date" id="dueDate" th:field="*{dueDate}" required>
</div>

<div>
<label for="status">Statut :</label>
<select id="status" th:field="*{status}" required>
<option value="À faire">À faire</option>
<option value="En cours">En cours</option>
<option value="Terminé">Terminé</option>
</select>
</div>

<div>
<button type="submit" th:text="${[Link] == null} ? 'Créer' : 'Modifier'"></button>
<a href="/tasks">Annuler</a>
</div>
</form>
</body>
</html>
2️⃣Template pour afficher les détails d’une tâche (task_detail.html)

<!DOCTYPE html>
<html xmlns:th="[Link]
<head>
<meta charset="UTF-8">
<title>Détails de la tâche</title>
</head>
<body>
<h1>Détails de la tâche</h1>

<p><strong>ID :</strong> <span th:text="${[Link]}"></span></p>


<p><strong>Contenu :</strong> <span th:text="${[Link]}"></span></p>
<p><strong>Catégorie :</strong> <span th:text="${[Link]}"></span></p>
<p><strong>Date de création :</strong> <span th:text="${[Link]}"></span></p>
<p><strong>Date d'échéance :</strong> <span th:text="${[Link]}"></span></p>
<p><strong>Statut :</strong> <span th:text="${[Link]}"></span></p>

<p>
<a th:href="@{'/tasks/' + ${[Link]} + '/edit'}">Modifier</a> |
<a th:href="/tasks">Retour à la liste</a>
</p>
</body>

🧩
</html>

Explications
• Le template de détail affiche toutes les informations d’une tâche spécifique.
• Les liens permettent de modifier la tâche ou de revenir à la liste complète.
• Le template de création/modification est flexible grâce à l’utilisation de [Link] pour
différencier création vs modification.
Avec ces deux templates, l’interface utilisateur est complète :
• Liste des tâches ([Link])
• Création et modification (task_form.html)
• Détails d’une tâche (task_detail.html)

Voici comment initialiser la base avec des catégories et des tâches de test dans Spring Boot, en
utilisant le CommandLineRunner que nous avions préparé :
package app;

import [Link];
import [Link];
import [Link];
import [Link];

import [Link];
import [Link];
import [Link];
import [Link];

import [Link];

@SpringBootApplication
public class TasksApplication implements CommandLineRunner {

@Autowired
private CategoryRepository categoryRepository;

@Autowired
private TaskRepository taskRepository;

public static void main(String[] args) {


[Link]([Link], args);
}

@Override
public void run(String... args) throws Exception {
// Vérifie si la base est vide
if ([Link]() == 0) {
// Création de catégories
Category cat1 = new Category("Travail");
Category cat2 = new Category("Personnel");
Category cat3 = new Category("Urgent");

[Link](cat1);
[Link](cat2);
[Link](cat3);

// Création de tâches de test


Task t1 = new Task(cat1, "Préparer le rapport annuel", [Link](),
[Link]().plusDays(5), "À faire");
Task t2 = new Task(cat2, "Acheter du lait", [Link](), [Link]().plusDays(1),
"À faire");
Task t3 = new Task(cat3, "Réparer la fuite", [Link](),
[Link]().plusDays(2), "En cours");

[Link](t1);
[Link](t2);
[Link](t3);

[Link]("Base initialisée avec des catégories et tâches de test.");


}
}

🧩
}

Explications
• [Link]() : permet de ne pas réinitialiser la base si elle contient déjà des
données.
• Création des catégories et tâches : on utilise save() pour persister les objets en base.
• Les dates sont générées avec [Link]() et plusDays(n).
• Une fois lancé, l’application contient déjà 3 catégories et 3 tâches de test.
Avec cette configuration, ton application Spring Boot est entièrement fonctionnelle :
• Les données sont pré-remplies,
• Tu peux afficher, créer, modifier et supprimer des tâches via l’interface web,
• Tu peux utiliser la console H2 pour vérifier les données
Voici un schéma résumé complet de l’architecture de notre application de gestion de tâches
Spring Boot avec JPA et Thymeleaf :
+--------------------------------------------------+
| Spring Boot |
| |
| +------------------+ +----------------+ |
| | Controllers | | Services | |
| |------------------| | (facultatif) | |
| | TaskController | | | |
| | | | | |
| +--------+---------+ +----------------+ |
| | |
| v |
| +------------------+ |
| | Repositories | <-- accès aux données|
| |------------------| |
| | TaskRepository | |
| | CategoryRepository| |
| +--------+---------+ |
| | |
| v |
| +------------------+ |
| | Entities / Models | |
| |------------------| |
| | Task | |
| | Category | |
| +------------------+ |
| |
+--------------------------------------------------+

+-------------------+
| Templates |
| (Thymeleaf) |
|-------------------|
| [Link] | <-- Liste des tâches
| task_form.html | <-- Création / modification
| task_detail.html | <-- Détail d’une tâche
+-------------------+

+-------------------+
| Base H2 |
|-------------------|
| tables : |
| - categories |
| - tasks |

🔹
+-------------------+

Flux des données


1. Utilisateur → Contrôleur
• L’utilisateur accède à une page web (/tasks, /tasks/new,
/tasks/{id}/edit, etc.)
• Le Controller reçoit la requête et prépare le modèle.
2. Contrôleur → Repository
• Le contrôleur utilise TaskRepository ou CategoryRepository pour interagir avec la
base.
• CRUD complet grâce à Spring Data JPA : save(), findAll(), findById(),
deleteById().
3. Repository → Base de données
• Les entités Task et Category sont mappées aux tables tasks et categories.
• La base H2 stocke les données persistantes.
4. Contrôleur → Template (Thymeleaf)
• Le contrôleur envoie les objets au template.
• Le template génère le HTML dynamique affiché dans le navigateur.

🔹 Points clés
• Entités : représentent les tables de la base.
• Repositories : DAO Spring Data, CRUD automatique.
• Contrôleur : gère les routes et prépare le modèle pour Thymeleaf.
• Templates : affichage HTML dynamique des données.
• Base H2 : persistance embarquée, simple pour TP.
Voici un résumé clair des différences entre JPA et Spring Data JPA :

1️⃣ JPA (Java Persistence API)


• Définition : JPA est une spécification Java standard pour la gestion de la persistance des
objets Java dans une base de données relationnelle.
• Objectif : Fournir un moyen indépendant du fournisseur pour mapper les classes Java sur
les tables SQL.
• Fonctionnalités principales :
• Mapping objet-relationnel (ORM) via annotations (@Entity, @Id, @OneToMany,
etc.).
• Gestion des entités et de leur cycle de vie (persist, merge, remove, find).
• Support des JPQL (Java Persistence Query Language) pour interroger la base de
manière orientée objet.
Voici un résumé clair des différences entre JPA et Spring Data JPA :

1️⃣ JPA (Java Persistence API)


• Définition : JPA est une spécification Java standard pour la gestion de la persistance des
objets Java dans une base de données relationnelle.
• Objectif : Fournir un moyen indépendant du fournisseur pour mapper les classes Java sur
les tables SQL.
• Fonctionnalités principales :
• Mapping objet-relationnel (ORM) via annotations (@Entity, @Id, @OneToMany,
etc.).
• Gestion des entités et de leur cycle de vie (persist, merge, remove, find).
• Support des JPQL (Java Persistence Query Language) pour interroger la base de
manière orientée objet.
Limite :
• C’est une spécification, il n’y a pas de code concret pour le DAO.
• Il faut écrire soi-même les DAO ou les repositories pour effectuer les opérations CRUD.

2️⃣ Spring Data JPA


• Définition : C’est un projet Spring qui simplifie l’utilisation de JPA en fournissant des
implémentations automatiques pour les repositories.
• Objectif : Réduire le code répétitif pour manipuler les entités et les bases relationnelles.
• Fonctionnalités principales :
• CRUD automatique via des interfaces (CrudRepository, JpaRepository).
• Méthodes de recherche automatiques générées par nommage des méthodes
(findByStatus, findByCategoryName).
• Pagination et tri intégrés.
• Intégration facile avec Spring Boot et Spring MVC.
• Avantage :
• Presque aucun code JDBC ou JPQL à écrire pour les opérations courantes.
• Spring gère les transactions et l’injection des repositories.
3️⃣Comparatif rapide

Aspect JPA Spring Data JPA


Nature Spécification Java Extension Spring basée sur JPA
CRUD À coder soi-même Automatique via repository
Requêtes JPQL ou Criteria API JPQL + méthodes dérivées par nom
Réduction de code Faible Très élevée
Intégration Spring Boot Manuelle Native et très simple
Transactions À gérer manuellement ou via EJB Gérées automatiquement par Spring

Vous aimerez peut-être aussi