MongoDB to potężny, zorientowany na dokumenty system zarządzania bazami danych o otwartym kodzie źródłowym, znany ze swojej elastyczności, skalowalności i szerokiego zakresu funkcji. Jest to część rodziny systemów baz danych NoSQL, zaprojektowanych do obsługi dużych ilości danych i zapewniających wysoką wydajność, wysoką dostępność i łatwą skalowalność. MongoDB przechowuje dane w dokumentach podobnych do JSON w parach klucz-wartość, co pozwala na Java Spring Boot aby wykorzystać Struktura JSON w kodzie.
Spring Boot z MongoDB
Możemy natknąć się na sytuacje, w których używamy Spring Boot z Bazy danych SQL, ale aby wykorzystać MongoDB ze Spring boot, Spring Data MongoDB oferuje lekki dostęp do danych repozytorium i obsługę bazy danych MongoDB, co zmniejsza złożoność kodu.
Zakładając, że mają Państwo dość dobre zrozumienie MongoDB, przyjrzymy się budowaniu aplikacji Spring Boot z Spring Data MongoDB.
Wymagania wstępne
6 kroków do stworzenia aplikacji Spring Boot z Spring REST i Spring Data MongoDB
W tym artykule użyłem MongoDB Atlas bazy danych, która jest wielochmurową usługą bazodanową dla deweloperów, która umożliwia bezpłatne tworzenie i utrzymywanie baz danych w chmurze. Użyłem również MongoDB Compass, narzędzie GUI do wizualizacji bazy danych. Jeśli nie mają Państwo konta w MongoDB Atlas, można je wypróbować za darmo.
Krok 1: Tworzenie aplikacji Spring Boot za pomocą Spring Initializer
W pierwszej kolejności należy utworzyć aplikację Spring Boot przy użyciu Spring Initializr, który generuje projekt Spring Boot z wybranymi zależnościami. Po wybraniu pól, jak pokazano na poniższym obrazku, proszę kliknąć przycisk Generate, iProszę przenieść wyodrębniony projekt do IDE.

Struktura projektu:

Krok 2: Konfiguracja bazy danych
Aby skonfigurować MongoDB w aplikacji Spring boot, dodamy adres URL bazy danych w pliku src/main/resources/application.properties jak pokazano poniżej:
spring.data.mongodb.uri = mongodb+srv://username:password@student.port.mongodb.net/student
Model:
MongoDB to nierelacyjna baza danych zorientowana na dokumenty. Stworzyliśmy Student oraz Adres Model Java do przechowywania obiektów. @Document adnotacja służy do podania niestandardowej nazwy kolekcji, a @Field służy do podania niestandardowej nazwy klucza dla obiektu.
W poniższym kodzie stworzyliśmy przykład zmiennych z różnymi typami danych, takimi jak Data, Lista itp.
Student.java
package com.example.studentmanagementsystem.model;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
import java.time.LocalDate;
import java.util.List;
@Document("Student")
public class Student {
    @Id
    @Indexed(unique = true)
    private String id;
    private String name;
    private double cgpa;
    @Field("has_arrears")
    private boolean hasArrears;
    @Field("course_list")
    private List<String> courseList;
    private Address address;
    @Field("enrollment_date")
    @JsonFormat
            (shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy")
    private LocalDate enrollmentDate;
}
Address.java
package com.example.studentmanagementsystem.model;
import jakarta.persistence.Entity;
import org.springframework.data.mongodb.core.mapping.Field;
@Entity
public class Address {
    private String street;
    private String city;
    private String state;
    private String country;
    @Field("zip_code")
    private String zipcode;
}
Krok 3: Tworzenie repozytorium
Stworzyliśmy interfejs StudentRepository, które rozciąga się na MongoRepository. MongoRepository to interfejs dostarczany przez Spring Data, który umożliwia predefiniowane operacje CRUD i automatyczne mapowanie. Operacje CRUD lub REST to nic innego jak komunikacja między usługami i danymi w trwały i ustrukturyzowany sposób.
Spring @Repository służy do wskazania, że klasa zapewnia mechanizm przechowywania, pobierania, wyszukiwania, aktualizacji i usuwania operacji na obiektach i działa jako warstwa trwałości.
Utwórzmy metody findBy do pobierania danych z bazy danych, jak pokazano w poniższym kodzie:
package com.example.studentmanagementsystem.repository;
import com.example.studentmanagementsystem.model.Student;
import org.springframework.data.mongodb.repository.Aggregation;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import java.time.LocalDate;
import java.util.List;
@Repository
public interface StudentRepository extends MongoRepository<Student, String> {
    List<Student> findByNameAndCgpa(String name, Double cgpa);
    Student findByAddress_City(String city);
    List<Student> findByAddress_CountryOrHasArrears(String country, Boolean hasArrears);
    List<Student> findByEnrollmentDateBetweenOrderByEnrollmentDate(LocalDate startDate, LocalDate endDate);
    List<Student> findByCgpaGreaterThanEqual(Double cgpa);
    String findByNameIgnoreCase(String name);
    List<Student> findByCgpaOrderByNameDesc(Double cgpa, String name);
  
//aggregation example for overall average cgpa
    @Aggregation("{ $group : { _id : null, averageCgpa : { $avg : $cgpa} } }")
    Long avgCgpa();
}
Krok 4: Tworzenie usługi
Zbudujmy warstwę usług dla repozytorium Student, aby komunikować się z danymi w bazie danych MongoDB. Stworzymy kilka metod, aby wykorzystać operacje CRUD, takie jak metody wstawiania, pobierania i usuwania.
package com.example.studentmanagementsystem.service;
import com.example.studentmanagementsystem.model.Student;
import com.example.studentmanagementsystem.repository.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
@Service
public class StudentService {
    @Autowired
    private StudentRepository studentRepo;
    public void addStudentData(Student studentDetails) {
        studentRepo.insert(studentDetails);
    }
    public void addMultipleStudentsData(List<Student> studentsDetail) {
        studentRepo.insert(studentsDetail);
    }
    public List<Student> fetchAllStudentsData() {
        return studentRepo.findAll();
    }
    public Optional<Student> fetchStudentDataById(String id) {
        return studentRepo.findById(id);
    }
    public List<Student> fetchStudentDataByNameAndCgpa(String name, Double cgpa) {
        return studentRepo.findByNameAndCgpa(name, cgpa);
    }
    public Student fetchStudentDataByCity(String city) {
        return studentRepo.findByAddress_City(city);
    }
    public List<Student> fetchStudentDataByCountryOrArrears(String country, Boolean hasArrears) {
        return studentRepo.findByAddress_CountryOrHasArrears(country, hasArrears);
    }
    public List<Student> fetchStudentDataByCgpa(Double cgpa) {
        return studentRepo.findByCgpaGreaterThanEqual(cgpa);
    }
    public List<Student> fetchStudentDataByEnrollmentDate(LocalDate startDate, LocalDate endDate) {
        return studentRepo.findByEnrollmentDateBetweenOrderByEnrollmentDate(startDate, endDate);
    }
    public List<Student> fetchStudentDataByCgpaAndName(Double cgpa, String name) {
        return studentRepo.findByCgpaOrderByNameDesc(cgpa, name);
    }
    public Long fetchAverageCgpa() {
        return studentRepo.avgCgpa();
    }
    public String fetchStudentDataByName(String name) {
        return studentRepo.findByNameIgnoreCase(name);
    }
    public void deleteStudentData(Student studentDetails) {
        studentRepo.insert(studentDetails);
    }
    public void deleteAllStudentData() {
        studentRepo.deleteAll();
    }
}
Krok 5: Tworzenie kontrolera
Następnie należy utworzyć wywołania CRUD REST API dla zasobu Student w celu pobierania, wstawiania lub usuwania zasobów w bazie danych MongoDB.
The Spring @RestController jest używana do tworzenia usług internetowych RESTful i łączy w sobie adnotacje @Controller i @Responsebody, ułatwiając pisanie metod obsługi.
package com.example.studentmanagementsystem.controller;
import com.example.studentmanagementsystem.model.Student;
import com.example.studentmanagementsystem.service.StudentService;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
@RestController
@RequestMapping("/student")
public class StudentController {
    @Autowired
    private StudentService studentService;
    @PostMapping("/addStudent")
    public void populateStudentData(@RequestBody Student student){
          studentService.addStudentData(student);
    }
    @PostMapping("/addStudentsData")
    public void populateStudentsData(@RequestBody List<Student> students){
        studentService.addMultipleStudentsData(students);
    }
    @GetMapping("/getAllStudentsData")
    public List<Student> fetchAllStudentsData(){
        return studentService.fetchAllStudentsData();
    }
    @GetMapping("/getStudentById/{id}")
    public Optional<Student> fetchStudentDataById(@PathVariable String id){
       return studentService.fetchStudentDataById(id);
    }
    @GetMapping("/getStudentByNameAndCgpa")
    public List<Student> fetchStudentDataByNameAndCgpa(@RequestParam String name, @RequestParam Double cgpa){
        return studentService.fetchStudentDataByNameAndCgpa(name, cgpa);
    }
    @GetMapping("/getStudentByCity/{city}")
    public Student fetchStudentDataByCity(@PathVariable String city){
        return studentService.fetchStudentDataByCity(city);
    }
    @GetMapping("/getStudentByCountryOrArrears")
    public List<Student> fetchStudentDataByCountryOrArrears(@RequestParam String country,@RequestParam Boolean hasArrears){
        return studentService.fetchStudentDataByCountryOrArrears(country, hasArrears);
    }
    @GetMapping("/getStudentByEnrollmentDate")
    public List<Student> fetchStudentDataByEnrollmentDate(@JsonFormat
                                                                      (shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy") LocalDate startDate, @JsonFormat
            (shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy") LocalDate endDate){
        return studentService.fetchStudentDataByEnrollmentDate(startDate, endDate);
    }
    @GetMapping("/getStudentByName")
    public String fetchStudentDataByName(@RequestParam String name){
        return studentService.fetchStudentDataByName(name);
    }
    @GetMapping("/getStudentByCgpa")
    public List<Student> fetchStudentDataByCgpa(@RequestParam Double cgpa){
        return studentService.fetchStudentDataByCgpa(cgpa);
    }
    @GetMapping("/getAvgCgpa")
    public Long fetchStudentAvgCgpa(){
        return studentService.fetchAverageCgpa();
    }
    @DeleteMapping("/deleteStudent")
    public void deleteStudentData(Student student){
        studentService.deleteStudentData(student);
    }
    @DeleteMapping("/deleteAllStudents")
    public void deleteAllStudentsData(){
        studentService.deleteAllStudentData();
    }
}
Krok 6: Testowanie
Przetestujmy teraz jedno z wywołań API w Postmanie, aby pobrać dane z bazy danych, jak pokazano na poniższym obrazku.
Poniższa metoda HTTP zwraca wszystkie informacje o uczniu w tablicy obiektów JSON.
- Metoda: GET
 
Adres URL żądania: http://localhost:8080/student/getAllStudentsData

Zbudowaliśmy aplikację Spring Boot wykorzystującą bazę danych MongoDB i stworzyliśmy operacje CRUD, takie jak tworzenie, usuwanie i pobieranie danych z bazy danych, w tym różne sposoby pobierania danych. Spring Data MongoDB pomaga nam korzystać z wbudowanych metod dla operacji CRUD, co zmniejsza złożoność kodu w warstwie trwałości.