Je bent net begonnen als developer bij een bedrijf dat TV's verkoopt: Tech It Easy. Tijdens de cursus Spring Boot ga jij een backend applicatie programmeren voor het bedrijf. De winkel heeft een inventaris van televisies die moet worden bijgehouden. Na iedere les gaan we deze applicatie een stukje verder uitbouwen door middel van de huiswerkopdrachten. Zo krijg je stap-voor-stap meer ervaring in het bouwen van een backend applicatie. Aan het einde van de cursus zullen we een werkende Tech It Easy backend applicatie hebben!
Je hebt inmiddels je applicatie draaiende gekregen. Dit geeft je de mogelijkheid om in een database bij te houden welke tv's er zijn in de inventaris van TechItEasy. Als je de benamingen hebt aangehouden die we tot nu toe hebben gebruikt, kunnen we een data.sql gaan maken waardoor we gegevens in de database kunnen zetten. Dit is een soort van pre-fill van je database.
In deze opdracht ga je aan de slag met het toevoegen van relaties aan je applicatie.
De opdracht moet voldoen aan de volgende voorwaarden:
Het project bevat de volgende models
:
Television
RemoteController
met de variables: -Longid
-StringcompatibleWith
-StringbatteryType
-Stringname
-Stringbrand
-Doubleprice
-IntegeroriginalStock
CI-Module
met de variables: -Longid
-Stringname
-Stringtype
-Doubleprice
WallBracket
met de variables: -Longid
-Stringsize
-Booleanadjustable
-Stringname
-Doubleprice
Voor elk van deze modellen bevat je applicatie ook eenRepository
,Controller
,Dto
,InputDto
en eenService
.
Daarnaast bevat het project:
- Een
OneToOne
relatie tussenTelevision
enRemoteController
- Een
OneToMany
relatie tussenTelevision
enCI-Module
- Een
ManyToMany
relatie tussenTelevision
enWallBracket
Je mag de constructors uit de modellen weglaten. Deze vult Spring Boot automatisch in als ze niet gedefinieerd zijn. Ook uit de Television
mogen de constructors verwijderd worden.
Let op: het is uitdagender om jouw eigen stappenplan te maken. Mocht je niet zo goed weten waar je moet beginnen, kun je onderstaand stappenplan volgen:
- Maak in de map
models
een klasse aan voorRemoteController
,CI-Module
enWallBracket
(voeg de juiste annotatie, variables, getters&setters en constructors toe). - Maak in de map
repositories
voor elk model eenRepository
aan (die elk deJpaRepository
extends bevat). - Maak in de map
controllers
voor elk model eenController
aan (met juiste annotatie, constructor en requestMappings). - Maak in de map
dtos
voor elk model eenDto
enInputDto
aan (met juiste variables en toewijzingen). - Maak in de map
services
voor elk model eenService
aan (met juiste annotatie, constructor en functions). - Leg een OneToOne relatie tussen
Television
enRemoteController
door in beide models @OneToOne toe te voegen, gevolgd door het model waar de relatie mee ligt in de vorm vanModel
object
(bijvoorbeeldTelevision
television
) op de volgende regel. - Een OneToOne relatie heeft een eigenaar nodig. Maak de
Television
eigenaar door inRemoteController
achter de @OneToOne mappedBy toe te voegen op deze manier _@OneToOne(mappedBy = "remotecontroller"). Dit zorgt ervoor dat in deTelevision
tabel een kolom wordt toegevoegd met de naamremotecontroller_id
. Vergeet niet de getter en setter toe te voegen na het leggen van de relatie in de modellen. - Om deze kolom te vullen zal je in servicelaag ook een functie moeten maken die een koppeling maakt tussen de
Television
en deRemoteController
. Dit doe je in deTelevisionService
. - Voeg de functie "assignRemoteControllerToTelevision" toe in de
TelevisionService
. Zoals je ziet, herkent deTelevisionService
deRemoteControllerRepository
niet, dit komt omdat we deze nog niet gekoppeld hebben in de constructor, gelukkig hoef je niet alles opnieuw te doen. Je kan bovenaan in deTelevisionService
onder de privateTelevisionRepository
een privateRemoteControllerRepository
declareren. En dan in de bestaande constructor deze toevoegen op dezelfde manier als deTelevisionRepository
. Dit resulteert in:
public TelevisionService (TelevisionRepository televisionRepository,
RemoteControllerRepository remoteControllerRepository) {
this.televisionRepository = televisionRepository;
this.remoteControllerRepository = remoteControllerRepository;
}
- Om deze functie uit te kunnen voeren moet je in de
TelevisionController
een PutRequest maken met endpoint "/televisions/{id}/remotecontroller" om aan te spreken. Voeg deze toe en geef de televisionId mee als @PathVariable en de remoteControllerId als @RequestBody door middel van eenIdInputDto
input. - Hiervoor missen we nog de
IdInputDto
. Maak in het mapjeDtos
een nieuwe klasse aan voor deIdInputDto
. Declareer in deze dto een public Long id toe, meer hoeft er niet in. - Gefeliciteerd, je hebt zo juist de eerste relatie gelegd in je applicatie!
- Alleen als je nu met een get alle
Televisions
ophaalt, zie je geenRemoteController
. Dit komt omdat we in deTelevisionDto
nog niks hebben verteld over deRemoteController
. De makkelijkste manier om hier de uitbreiding te leggen is depublic RemoteControllerDto remoteController;
toe te voegen aan de variabele van deTelevisionDto
- Test alle functies die je tot nu toe hebt gemaakt met Postman.
Je hebt nu de relatie tussen de televisie en remoteController gemaakt. Maak nu relatie tussen Televisie en CiModule en Televisie en Wallbracket.
Mocht je er niet uit komen:
Stappenplan Televisie koppelen aan CiModule
- Maak de Television eigenaar door in CiModule achter @OneToMany mappedBy toe te voegen.
- Voeg in Television @ManyToOne(fetch = FetchType.EAGER) en @JoinColumn(name = "ci_module_id") toe.
- Vergeet de getter en setter niet.
- Maak een functie in TelevisionService om een CiModule aan een Television te koppelen.
- Voeg in TelevisionService een private CiModuleRepository toe en initialiseer deze in de constructor.
- Voeg de functie assignCiModuleToTelevision toe.
- Maak in de TelevisionController een PUT endpoint "/televisions/{id}/cimodule" aan.
- Gebruik @PathVariable voor televisionId en @RequestBody met een IdInputDto voor cimoduleId.
- Voeg in TelevisionDto de variabele public CiModuleDto ciModuleDto; toe.
- Test alle functies die je tot nu toe hebt gemaakt met Postman.
- Test onder andere het koppelen van een CiModule aan een Television en het ophalen van alle Televisions om te controleren of de CiModule correct is gekoppeld.
Stappenplan Televisie koppelen aan WallBracket
- Maak de Television eigenaar door in WallBracket achter @ManyToMany mappedBy toe te voegen.
- Voeg in Television
@ManyToMany @JoinTable(name = "television_Wallbrackets", joinColumns @JoinColumn(name = "television"), inverseJoinColumns = @JoinColumn(name = "wallbracket")
toe. - Vergeet de getter en setter niet.
- Maak een functie in TelevisionService om een WallBracket aan een Television te koppelen.
- Voeg in TelevisionService een private WallBracketRepository toe en initialiseer deze in de constructor.
- Voeg de functie assignWallBracketToTelevision toe.
- Maak in de TelevisionController een PUT endpoint "/televisions/{id}/WallBracket" aan.
- Gebruik @PathVariable voor televisionId en @RequestBody met een IdInputDto voor de WallBracket.
- Voeg in TelevisionDto de variabele public WallBracketDto wallBracketdto; toe.
- Test alle functies die je tot nu toe hebt gemaakt met Postman.
- Test onder andere het koppelen van een WallBracket aan een Television en het ophalen van alle Televisions om te controleren of de WallBracket correct is gekoppeld.