Logika aplikacji
Rozbudowa modelu danych
- Rozszerz model, uzupełniając brakujące adnotacje JPA w klasach
CourseiGrade, a następnie zdefiniuj dla nich interfejsy repozytoriów. Model powinien odwzorowywać poniższy diagram:

-
Wygeneruj przykładowe dane w klasie konfiguracji: utwórz dwa przedmioty, dodaj do nich po kilku studentów, a następnie utwórz oceny z każdego przedmiotu. Możesz wykorzystać poniższy kod:
Student kowalski = new Student("Jan", "Kowalski", LocalDate.now(), "123456"); Student budynek = new Student("Piotr", "Budynek", LocalDate.now(), "6547891"); Student menczystaty = new Student("Henryk", "Menczystaty", LocalDate.now(), "848565"); var to = new Course("Technologie obiektowe"); var po = new Course("Programowanie obiektowe"); to.assignStudent(kowalski); to.assignStudent(budynek); po.assignStudent(menczystaty); Grade grade1 = new Grade(5); kowalski.giveGrade(grade1); Grade grade2 = new Grade(4); kowalski.giveGrade(grade2); Grade grade3 = new Grade(3); budynek.giveGrade(grade3); Grade grade4 = new Grade(2); menczystaty.giveGrade(grade4); gradeRepository.saveAll(List.of(grade1, grade2, grade3, grade4)); studentRepository.saveAll(List.of(kowalski, budynek, menczystaty)); courseRepository.saveAll(List.of(to, po)); -
Zweryfikuj, czy po uruchomieniu aplikacji tworzą się odpowiednie struktury i dane w bazie.
Praca z API i rozbudowa warstwy usług
-
Napisz kontrolery, które udostępnią informacje o studentach i przedmiotach:
-
Dodaj metodę do pobierania wszystkich przedmiotów. Czy json zwrócony przez zapytanie zawiera również dane o studentach? Dlaczego? W jaki sposób zmodyfikować program tak, by zwracał np. same identyfikatory i nazwy kursów, bez studentów?
Odpowiedź - kliknij
Kontrolery należą do tzw. warstwy prezentacji. Ich zadaniem jest tłumaczenie modelu aplikacji na podstać możliwą do przetworzenia po stronie np. fronetendu. W tym przypadku takim formatem jest JSON, którego tworzeniem zajmuje się Spring. Można, a czasem wręcz trzeba wprowadzać tu formę pośrednią, tzw. DTO (Data Transfer Object), którą kontroler powinien tworzyć i zwracać zamiast oryginalnego obiektu (w tym przypadku
CourseDtozamiastCourse).Alternatywą jest ingerowanie w sam model aplikacji, np. używając adnotacji
@JsonIgnore, ale nie jest to dobre architektonicznie podejście i należy go unikać! -
Dodaj metodę do pobierania studentów zapisanych na przedmiot o podanym id. W tym celu stwórz nowy mapping w kontrolerze kursu i wykorzystaj mechanizm
@PathVariable.
-
-
Dodaj metodę do pobierania studenta po numerze indeksu: Wskazówka: kontroler powinien udostępniać taką usługę pod adresem:
/students?indexNumber=x. Wykorzystaj adnotację@RequestParam. Zadbaj o to by parametr był opcjonalny (żeby dalej dalo się pobierać pełną listę studentów). Więcej na temat obsługi parametrów tutaj (opens in a new tab). W warstwie repozytorium dodaj odpowiednie zapytanie korzystając z tzw. query method (opens in a new tab). -
W dalszych krokach będziemy m. in. tworzyli zapytania innego typu niż GET, do przetestowania których nie wystarczy już sama przeglądarka. Można korzystać z zewnętrznych narzędzi (curl, Postman), ale w przypadku projektu Spring Boot bardzo łatwo podpiąć narzędzie do generowania interaktywnej dokumentacji API - Swagger. Aby go skonfigurować wystarczy dodać do gradle'a paczkę:
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0'Po ponownym uruchomieniu aplikacji Swagger będzie dostępny pod domyślnym adresem: http://localhost:8080/swagger-ui.html (opens in a new tab)
-
Dodaj do kontrolera dla studenta możliwość dodania oceny z danego przedmiotu. Jakiego typu zapytanie REST będzie tutaj potrzebne? W zadaniu konieczne będzie wykorzystanie adnotacji
@Transactional. Dlaczego? Przetestuj rozwiązanie z wykorzystaniem Swaggera. -
Dodaj usługę w
StudentService, która umożliwi wyliczenie średniej dla studenta, ze wszystkich przedmiotów, na które jest zapisany. Spróbuj zrealizować to zadanie w całości po stronie bazy danych, tj. tworząc odpowiednie zapytanie w warstwie repozytorium. Tym razem może być to niemożliwe przy użyciu standardowego query method - w takiej sytuacji możemy napisać własne query w JPQL.