Préambule
Ce deuxième TP consiste à mettre en place des mappings relationnels entre quelques tables, afin d'utiliser les connaissances des TD 2 & 3.
1°/ Items et catégories d'items
Dans le premier TP, il n'y a aucune relation établie entre les tables rpgitems et categories grâce à un mapping relationnel. En effet, la relation est faîte "à la main", en utilisant dans la table rpgitems une colonne indiquant l'id d'un élément de categories.
Normalement, il faudrait que cette colonne soit une clé étrangère faisant référence à la clé primaire de categories.
Tester le mapping avec une requête pour récupérer un ou plusieurs items et vérifier que le JSON contient les informations liées à la catégorie de l'item et pas seulement son id.
2°/ Rues et boutiques
L'objectif de cette partie est de créer des rues et des boutiques, sachant qu'une rue peut contenir plusieurs boutiques, mais qu'une boutique n'est présente que dans une seule rue.
Exercice 1 :
- Créer les classes entités Street et Shop pour représenter les rues et les boutiques, sachant qu'elles n'ont que deux attributs (hors mapping relationnel) : Long id et String name. Les tables associées sont nommées streets et shops.
- Modifier ces classes pour établir un mapping te type one-to-many bidirectionnel, sachant qu'une rune peut contenir plusieurs boutiques mais qu'une boutique n'est présente que dans une seule rue.
- Modifier le fichier data.sql afin d'ajouter deux rues contenant chacune deux boutiques (leurs noms sont libres)
- Créer les repository StreetsRepository et ShopsRepository, en déclarant pour chacune une méthode pour retrouver un élément à partir de son nom.
- Créer les service StreetsService et ShopsService, contenant deux méthodes pour récupérer un élément par id ou bien par nom, grâce aux repository.
- Créer le contrôleur StreetsController, avec les routes :
- [GET] /rpg/streets/{id} : pour récupérer une rue par son id,
- [GET] /rpg/streets/byname/{name} : pour récupérer une rue par son nom.
- Créer le contrôleur ShopsController, avec les routes :
- [GET] /rpg/shops/{id} : pour récupérer une boutique par son id,
- [GET] /rpg/shops/byname/{name} : pour récupérer une boutique par son nom.
Tester le mapping en récupérant une rue. Normalement, cela aboutit à une erreur à cause de la relation bidirectionnelle et du fait que la sérialisation automatique entre dans une récursion infinie.
Exercice 2 :
- Créer la classe StreetDTO avec comme attribut le nom de la rue plus une liste des noms des boutiques de la rue. Cette classe contient également un constructeur prenant en paramètre une instance de Street.
- Créer la classe ShopDTO avec comme attribut le nom de la boutique. Cette classe contient également un constructeur prenant en paramètre une instance de Shop.
- Modifier les contrôleurs StreetsController et ShopController pour qu'ils renvoient des objet StreetDTO et ShopDTO, au lieu de Street et Shop.
Tester de nouveau le mapping en récupérant une rue et une boutique. Cette fois, il n'y a normalement pas d'erreur.
3°/ Boutique et items
L'objectif de cette partie est de créer des boutiques qui vont vendre des items. D'un point de vue relationnel, cela implique une relation de type *,*. Mais pour compliquer un peu, chaque boutique possède un certain nombre d'exemplaires d'items en stock et pratique ses propres promotions sur ces items. Cela implique que la table intermédiaire entre shops et rpgitems contienne ces informations et qu'il va falloir créer des mappings one-to-many et/ou many-to-one entre les 3 tables.
Exercice :
- Comme montré dans le TD 3, créer une classe ShopsItemsKey, de façon à constituer un couple de clés étrangères "embarquable",
- Créer la classe entité ShopsItems, associée à la table shopsitems, utilisant ShopsItemsKey comme clé embarquée, avec comme attributs : int stock et double promo.
- Modifier Shop et ShopsItems afin d'établir entre les deux une relation one-to-many+many-to-one bidirectionnelle.
- Modifier ShopsItems et RpgItems afin d'établir entre les deux une relation many-to-one unidirectionnelle : on n'a pas besoin de connaître directement quelle boutique vend un item donné.
- Remplir la table shopsitems, soit via data.sql, soit en lisant un csv, en mettant 2/3 item dans chaque boutique (le stock et la promo sont libres)
Tester le mapping en récupérant une boutique. Si tout va bien, le JSON reçu contient également les informations des items vendus par la boutique.