Skip to content

Spring Data JPA

Spring Data JPA nous permettra de créer rapidement toutes les représentations d'objets et les relations de notre base de données. On tirera avantage de

  • Décorateurs pour nous permettre de décrire le schéma de la base de données
  • Génération automatique des tables et contraintes
  • JPA repositories
  • Création de requêtes personnalisées sécuritaires au besoin

Modèles

On modifiera un peu la création des modèles pour ajouter des décorateurs qui permettront l'interaction avec la base de données

Au niveau de la classe

  • @Entity : Nécessaire pour indiquer que la classe est une entité de la base de données
  • @Table(name = "nom_table") : Permet de nommer la table. Pratique si on veut un nommer notre table différemment du nom de la classe.

Au niveau des attributs

  • @Id: Nécessaire sur une propriété de la classe. Elle deviendra la clé primaire de cette entité.
  • @GeneratedValue(strategy = GenerationType.{type_voulu}) : à utiliser en complément de @Id. Cela permet d'indiquer à notre base de données comment on veut créer les clés primaires.

    • GenerationType.IDENTITY: Crée des identifiants séquentiels de type numérique qui s'auto incrémente.
    • GenerationType.UUID : Crée une chaine de caractères de type UUID pour les clés primaires.
  • @Column() : Permet de personnaliser la colonne en lui donnant différents paramètres

    • name : pour spécifier le nom de la colonne
    • nullable : pour indiquer si on accepte les valeurs null dans la colonne
    • lenght : La longueur du champ
    • unique : Ajoute une contrainte d'unicité.

Notez qu'on peut combiner ces décorateurs avec les décorateurs Lombok et ceux de validation

Repositories

La création des repositories reposera sur les fonctionnalités offertes par l'interface JpaRepository

  • On crée une nouvelle interface qui hérite de JpaRepository<T, ID>
  • public interface IExampleRepository extends JpaRepository<Classe, TypeDeLaClePrimaire>

Plusieurs méthodes existent par défaut telles que save, delete et findAll.

On peut facilement créer des méthodes qui vont récupérer des enregistrements de la base de données selon une ou plusieurs propriétés dans notre interface. On utilisera la syntaxe suivante pour le nom des méthodes pour que la requête se crée automatiquement.

find{NomClasse}By{NomAttribut}

Il est aussi possible de créer une requête personnalisée.

// Classe Chat
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Entity
@Table(name = "chats")
public class Chat {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "nom", nullable = false)
    private String  nom;
    private String  couleur;
    private Integer age;
}

// Interface IChatRepository
public interface IChatRepository extends JpaRepository<Chat, Long> {
    // Chercher par le nom exact
    List<Chat> findByNom(String nom);

    // Chercher par nom et couleur
    List<Chat> findByNomAndCouleur(String nom, String couleur);

    // Chercher par nom exact et couleur exacte et age exact
    List<Chats> findByNomAndCouleurAndAge(String nom, String couleur, Integer age);

    // Requête personnalisée pour chercher par nom semblable
    @Query("select c from Chats c where c.nom like %:nom%")
    List<Chat> chercherParNom(String nom);
}

Les requêtes personnalisés utilisent des requêtes paramétrées et offrent donc une protection contre l'injection SQL.

L'interface ainsi créée pourra être injectée dans un service afin de faire les requêtes à la base de données.