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.