Bases de données
Spring permet d'interagir avec des bases de données relationnelles et tout référentiel permettant de stocker des données.
- Spring : Transaction, Repository/DAO, JdbcTemplate
- Hibernate : Entités (classes Java correspondant à vos tables en base)
- JPA : norme JEE, Hibernate implémente JPA 1.0/2.0/2.1
DataSource
Spring Boot, via son fichier de configuration application.properties
, permet
de définir les paramètres d'accès à la base de données :
spring.datasource.url=jdbc:postgresql://server-name:server-port/database-name
spring.datasource.username=dbuser
spring.datasource.password=dbpass
Mise à jour schéma de base de données avec Flyway
Flyway est une bibliothèque qui permet de gérer les migrations de schéma d'une
base de données. Il vous permettra de stocker vos scripts SQL pour la création
des tables, colonnes, etc. Il suffit de placer vos scripts .sql dans le
répertoire src/main/resources/db/migration
avec un nom de la forme :
V1__description_des_modifs.sql
V2__une_version_suivante.sql
- etc.
Attention : un script Flyway ne doit plus être modifié une fois qu'il a été passé sur la base de données. Flyway conserve un historique des scripts et de leur contenu. Si vous voulez modifier un script, il vaut mieux créer un nouveau script, avec une version supérieure, et exécuter les commandes SQL permettant de faire les modifications souhaitées.
TP7 - Flyway
Créez un script de migration Flyway dans lequel vous créez les tables et colonnes suivantes :
- Table
categorie
avec les colonnes id (serial), nom (text) - Table
article
avec les colonnes id (serial), titre (text), corps (text), categorie_id (int) (FK vers catégorie)
JdbcTemplate
Pour envoyer des requêtes personnalisées à une base de données, Spring met à disposition un bean de la classe JdbcTemplate, que vous pouvez injecter dans vos classes Repository.
@Repository
public class ArticleRepository {
@Autowired
private JdbcTemplate jdbcTemplate;
public int getNombreArticle() {
String query = "select count(*) from article";
return this.jdbcTemplate.queryForObject(query, Integer.class);
}
public int getNombreArticlePourCategorie(Categorie categorie) {
String query = "select count(*) from article where categorie_id = ?";
return this.jdbcTemplate.queryForObject(query, Integer.class, categorie.getId());
}
}
Pour des objets plus complexes, il faut mapper les colonnes du résultats de la
requête aux attributs de nos objets. Pour cela, il faut implémenter l'interface
RowMapper<T>
et sa méthode T mapRow(ResultSet, int)
.
public class ArticleMapper implements RowMapper<Article> {
@Override
public Article mapRow(ResultSet rs, int rowNum) throws SQLException {
Article article = new Article();
article.setTitre(rs.getString("titre"));
article.setCorps(rs.getString("corps"));
// etc.
return article;
}
}
On peut ensuite utiliser ce RowMapper pour récupérer un ou plusieurs articles :
public Article getArticleById(int id) {
String query = "select * from article where id = ?";
Article article = this.jdbcTemplate.queryForObject(query, new ArticleMapper(), 1);
return article;
}
public List<Article> getAllArticles() {
List<Article> articles = this.jdbcTemplate.query("select * from article", new ArticleMapper());
return articles;
}
Dans le cas où vos noms de colonnes et d'attributs sont identiques, Spring met à disposition une implémentation du RowMapper qui se débrouille toute seule :
public List<Article> getAllArticles() {
return jdbcTemplate.query("select * from article ", new BeanPropertyRowMapper<>(Article.class));
}
Attention : dès qu'une colonne ne correspond pas à l'attribut de la classe,
l'attribut prendra la valeur null
.
Permet également insertion/mise à jour/suppression avec la méthode update
.
this.jdbcTemplate.update(
"insert into article (id, titre) values (?, ?)",
8, "Titre de l'article");
TP8 - JdbcTemplate
- Ajoutez une catégorie et deux articles dans votre base avec PGAdmin.
- Créez une classe @Repository avec un JdbcTemplate et une méthode pour récupérer un article à partir de son ID.
- Créez un controller qui propose un GetMapping acceptant un ID et retournant un Article avec ses différents attributs.
- Injectez votre repository dans votre controller et appelez la méthode codée au point 2 pour récupérer un article
- Vérifiez en appelant votre controller que vous obtenez votre article en JSON