Как создать Rest API с помощью Spring Boot, используя MySQL и JPA
Всем привет! В течение прошлого года для полноценной веб-разработки я изучал JavaScript. Для разнообразия я начал осваивать Java - мощный объектно-ориентированный язык.
В этом случае я нашел очень чистый и элегантный фреймворк под названием Spring Boot для создания серверной части.
Ранее при разработке JavaScript я использовал:
- Mongoose - ORM для базы данных Mongo
- Sequelize - ORM для MySQL
Для разработки, связанной с Java, существует множество ORM, таких как Hibernate, JPA (Java Persistence API) и Java Object-Oriented Querying.
Я предпочитаю строить с помощью JPA, который традиционно используется в приложениях Java.
Это было очень интересно, и мне потребовалось около недели, чтобы закончить, так как мне пришлось выучить Spring Boot (есть много аннотаций “@” и других интересных вещей), JPA и Hibernate.
Вся эта магия в основном делается с помощью аннотаций (символ «@»), используемых в Spring Boot.
Создание проекта Spring Boot Maven
Давайте создадим приложение проекта Spring Boot Maven по этой ссылке.
«Maven» - это инструмент управления проектами, используемый для управления зависимостями. Это как Node Package Manager (NPM) в среде разработки JS.
У нас есть package.json в NodeJS для управления зависимостями и pom.xml в Spring Boot для управления зависимостями.
В Group напишите любое имя, которое вы хотите. Обычно доменное имя организации пишется справа налево.
Например, наше доменное имя www.javaAPI.com, поэтому имя группы может быть com.javaAPI.www
Затем в Artifact введите имя нужной вам папки.
На правой стороне добавьте следующие зависимости:
- WEB - Чтобы использовать зависимости Spring (более старая среда Spring Boot использовалась для разработки веб-приложений)
- JPA - API персистентности Java
- MYSQL
Затем нажмите «Generate Project». В загрузках найдете rar-файл - распакуйте его. Затем откройте эту папку в вашей любимой IDE.
Нажмите на com.rest.API, и вы найдете файл ApiApplication.java с примерно следующим содержанием:
package com.rest.API; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ApiApplication {public static void main(String[] args) { SpringApplication.run(ApiApplication.class, args); } }
Этого кода достаточно для запуска вашего сервера. Обычно spring boot выполняется на localhost:8080.
Введите в свой терминал, как показано ниже:
mvn spring-boot:run
Посмотрите, как ваш localhost работает в веб-браузере на порту 8080. Он выглядит пустым, поскольку мы еще ничего не сделали.
Давайте рассмотрим файлы и их теги
Если вы посмотрите на файл pom.xml, вы можете заметить, что зависимости, которые вы вводите при создании приложения в Spring Initialize, такие как MySQL, JPA и Web, будут внутри тега .
Зависимости для начинающего и тестирующего являются ядром для создания приложения Spring Boot для обслуживания на сервере.
Теперь перейдем к APIApplication.java, который является основным файлом.
package com.rest.API; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ApiApplication { public static void main(String[] args) { SpringApplication.run(ApiApplication.class, args); } }
Здесь название пакета находится в первой строке кода. Используя это имя пакета, вы можете импортировать любой класс, метод или экземпляры в другой файл пакета.
После этого два модуля импортируются из пакета «org.springframework.boot».
- SpringApplication
- SpringBootApplication
Поскольку Spring boot является обновленной средой разработки приложений Spring, ему нужны пакеты Spring Application, а также его специальные пакеты.
После этого используется аннотация @SpringBootApplication. Эта аннотация состоит из аннотации, которая используется в Spring:
- @Component - сообщает компилятору, что следующий класс является компонентом, который должен быть включен при компиляции всего приложения.
- @ComponentScan - Этот сканирует, какие пакеты мы собираемся использовать в следующем классе Java.
- @EnableAutoConfiguration - включает механизм автоконфигурации Spring Boot для импорта важных модулей для запуска Spring Boot.
Это аннотации, используемые для запуска Spring Boot Application для запуска на сервере.
Давайте создадим модель для наших данных
Давайте создадим класс Model для сохранения, извлечения, обновления и удаления сведений о книге.
Для этого мне нужно создать новый пакет с именем model, а внутри него создать класс Book.java для размещения моего кода.
package com.rest.API.model; import javax.persistence.*; import javax.validation.constraints.NotBlank; @Entity @Table(name = "books") public class Book { @Id @GeneratedValue private Long id; @NotBlank private String book_name; @NotBlank private String author_name; @NotBlank private String isbn; public Book(){ super(); } public Book(Long id, String book_name, String author_name, String isbn) { super(); this.id = id; this.book_name = book_name; this.author_name = author_name; this.isbn=isbn; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getBook_name() { return book_name; } public void setBook_name(String book_name) { this.book_name = book_name; } public String getAuthor_name() { return author_name; } public void setAuthor_name(String author_name) { this.author_name = author_name; } public String getIsbn() { return isbn; } public void setIsbn(String isbn) { this.isbn = isbn; } }
Здесь я использую JPA (Java Persistence API), который представляет собой набор классов и методов для постоянного хранения данных в базе данных.
@Entity - используется для обозначения того, что этот класс будет сущностью в базе данных.
@Table - принимает значение name, которое вы собираетесь назвать своей таблицей
@Id - обозначает, что id является первичным ключом / идентифицирующим ключом для этой таблицы.
@NotBlank - используется, чтобы сказать, что эти атрибуты не должны быть пустыми.
Кроме этого есть пустой конструктор, который имеет супер метод для удовлетворения таможенных правил JPA. Методы получения и установки обычно находятся в классе POJO (обычный старый объект Java).
Создание Repository
Далее мы собираемся создать пакет репозитория для управления базой данных в Java.
Создайте интерфейс с именем BookRepository.java внутри пакета repository.
package com.rest.API.repository; import com.rest.API.model.Book; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface BookRepository extends JpaRepository{ }
Я импортировал пакет JpaRepository для использования этого репозитория в интерфейсе BookRepository, подключив мою последнюю модель Book для выполнения CRUD операций.
В этих репозиториях уже есть встроенные методы для выполнения операций CRUD.
Например:
- .findAll() - получить все данные
- .save() - сохранить полученные данные
- .delete() - удалить данные
Внутри тега <> мы берем имя модели, которую мы будем использовать, и тип данных первичного ключа.
@Repository: аннотация, используемая для обозначения компонента DAO (объекта доступа к данным) на постоянном уровне.
Он сообщает компилятору, что интерфейс будет использовать репозиторий для выполнения операций с базой данных.
Создание контроллера и обработка исключений
Создайте новый пакет с именем controller, и внутри него создайте файл BookController.java, который содержит следующее.
package com.rest.API.controller; import com.rest.API.exception.BookNotFoundException; import com.rest.API.model.Book; import com.rest.API.repository.BookRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.http.ResponseEntity; import javax.validation.Valid; import java.util.List; @RestController public class BookController { @Autowired BookRepository bookRepository; // Получить все записи @GetMapping("/books") public ListgetAllNotes() { return bookRepository.findAll(); } // Создать запись @PostMapping("/books") public Book createNote(@Valid @RequestBody Book book) { return bookRepository.save(book); } // Получить запись по id @GetMapping("/books/{id}") public Book getNoteById(@PathVariable(value = "id") Long bookId) throws BookNotFoundException { return bookRepository.findById(bookId) .orElseThrow(() -> new BookNotFoundException(bookId)); } // Обновить запись @PutMapping("/books/{id}") public Book updateNote(@PathVariable(value = "id") Long bookId, @Valid @RequestBody Book bookDetails) throws BookNotFoundException { Book book = bookRepository.findById(bookId) .orElseThrow(() -> new BookNotFoundException(bookId)); book.setBook_name(bookDetails.getBook_name()); book.setAuthor_name(bookDetails.getAuthor_name()); book.setIsbn(bookDetails.getIsbn()); Book updatedBook = bookRepository.save(book); return updatedBook; } // Удалить запись по id @DeleteMapping("/books/{id}") public ResponseEntity> deleteBook(@PathVariable(value = "id") Long bookId) throws BookNotFoundException { Book book = bookRepository.findById(bookId) .orElseThrow(() -> new BookNotFoundException(bookId)); bookRepository.delete(book); return ResponseEntity.ok().build(); } }
Первый импортированный пакет предназначен для исключений BookNotFound (для которого мы собираемся позже создать файл).
Объяснение аннотаций которые мы здесь использовали:
1. RestController: эта аннотация используется для обозначения каждого метода в аннотированном классе как объект домена.
Так что же такое объект доменна...?
Это просто говорит о том, что Domain Object == Business Object.
Они обычно представлены сущностями и объектами значений, относящимися к конечной точке, которую мы даем для получения данных из базы данных.
2. Autowired: эта аннотация используется для автоматической связи bean классов.
Для этого вам нужно знать, что такое bean класс..?
По сути, Java Bean Class - это простой класс, который включает в себя множество объектов.
3. GetMapping: это интерфейс, который содержит путь конечной точки (uri) для выполнения метода Get. Этот интерфейс GetMapping использует интерфейс RequestMapping, который может иметь метод «path, value, params, headers» для выполнения метода Get в более ранних версиях Spring.
Теперь его использование упрощено с помощью GetMapping.
4. PostMapping: это интерфейс, который содержит путь к конечной точке (uri) для выполнения метода Post.
5. PutMapping: это интерфейс, который содержит путь конечной точки (uri) для выполнения метода Put для обновления записей.
6. DeleteMapping: это интерфейс, который содержит путь конечной точки (uri) для выполнения метода Delete.
В последних строках вы, вероятно, заметили ключевое слово «ResponseEntity».
Что это такое…??
Это класс Java, который наследует класс HttpEntity для манипулирования ответами HTTP. Независимо от того, является ли статус запроса соединения «200 ОК» или если есть какие-либо проблемы, выведите исключение из класса HttpEntity.
orElseThrow(): это метод, найденный в классе Optional в Java8, который был введен для обработки исключений. Необязательный класс предоставляет различные служебные методы для проверки наличия или отсутствия объекта, что помогает работать с NullPointerException.
orElseThrow - это метод, который возвращает значение, если оно присутствует, в противном случае вызывает исключение.
Создание NotFoundException, если такого book_id не существует
Так как метод orElseThrow создает исключение NotFound. Ниже приведена часть обработки исключений. Создайте файл BookNotFoundException.java внутри пакета exception.
package com.rest.API.exception; public class BookNotFoundException extends Exception { private long book_id; public BookNotFoundException(long book_id) { super(String.format("Book is not found with id : '%s'", book_id)); } }
Созданный класс расширяет суперкласс Exception. В конструкторе я передаю book_id и печатаю исключение.
Итак, это все…
Мы закончили часть REST API. Теперь вы можете создать приложение (которое было объяснено в части 1) и провести несколько тестирований с Postman.
Соединение с базой данных MySql
Внутри application.properties вашей папки ресурсов добавьте следующее:
## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties) spring.datasource.url = jdbc:mysql://localhost:3306/library spring.datasource.username = root //normally put your MySQL username spring.datasource.password = YOUR_MYSQL_PASSWORD ## Hibernate Properties # The SQL dialect makes Hibernate generate better SQL for the chosen database spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect # Hibernate ddl auto (create, create-drop, validate, update) spring.jpa.hibernate.ddl-auto = update
Мы создали базовый REST API в Spring Boot!
Если что-то не так или нужно исправить, пожалуйста, дайте мне знать в комментариях.