Сьогодні ми зробимо повноцінний додаток на Spring Boot і JPA. Розберемося, як створювати таблиці в базі даних через JPA-сутності, а також навчимося працювати з запитами до цих таблиць. Для практики зробимо міні‑додаток для керування каталогом книжок.
Крок 1: Створення нового Spring Boot проєкту
Якщо ти ще не створив проєкт, скористаємося зручним інструментом Spring Initializr. Бажане ім'я проєкту: library-management. Додай такі залежності:
- Spring Web
- Spring Data JPA
- H2 Database (або вибери іншу базу даних, з якою хочеш працювати)
Структура проєкту
Після створення проєкту структура виглядатиме приблизно так:
src/main/java/com/example/librarymanagement
├── LibraryManagementApplication.java
├── entity
│ └── Book.java
├── repository
│ └── BookRepository.java
├── controller
│ └── BookController.java
├── service
└── BookService.java
Крок 2: Налаштування файлу application.properties
Для конфігурації бази даних вкажи параметри підключення у файлі application.properties (або application.yml):
# Налаштування вбудованої бази даних H2
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.username=sa
spring.datasource.password=password
spring.datasource.driver-class-name=org.h2.Driver
# Генерація таблиць на основі JPA
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
Зверни увагу:
spring.jpa.hibernate.ddl-auto=updateвказує Hibernate автоматично оновлювати структуру бази даних відповідно до твоїх сутностей. Для продакшну рекомендовано використовуватиvalidateабо керувати схемою вручну.spring.jpa.show-sql=trueдозволяє бачити SQL-запити, які виконуються, у консолі.
Крок 3: Створення сутності Book
Тепер створимо сутність, яка буде представляти таблицю books у нашій базі. Помісти її в пакет entity.
package com.example.librarymanagement.entity;
import jakarta.persistence.*;
@Entity // Вказує, що це JPA-сутність
@Table(name = "books") // Ім'я таблиці
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) // Генерація ID
private Long id;
@Column(name = "title", nullable = false) // Поле з іменем "title", обов'язкове для заповнення
private String title;
@Column(name = "author", nullable = false)
private String author;
@Column(name = "year_published") // Поле з назвою "year_published"
private Integer yearPublished;
// Конструктори, геттери і сеттери
public Book() {}
public Book(String title, String author, Integer yearPublished) {
this.title = title;
this.author = author;
this.yearPublished = yearPublished;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Integer getYearPublished() {
return yearPublished;
}
public void setYearPublished(Integer yearPublished) {
this.yearPublished = yearPublished;
}
}
- Анотація
@Entityробить клас JPA-сутністю. - Анотація
@Tableзадає назву таблиці. Якщо її не вказати, JPA автоматично поставить ім'я таблиці за назвою класу. @Idі@GeneratedValueвказують, що полеid— це первинний ключ, який генерується автоматично.- Для кожного поля ми задали анотацію
@Column, щоб налаштувати відповідність між полями класу і стовпцями таблиці.
Крок 4: Створення репозиторію BookRepository
Механіка Spring Data JPA дозволяє нам створювати репозиторії без необхідності писати код для базових операцій. Усі основні CRUD-методи вже реалізовані в інтерфейсі JpaRepository.
package com.example.librarymanagement.repository;
import com.example.librarymanagement.entity.Book;
import org.springframework.data.jpa.repository.JpaRepository;
public interface BookRepository extends JpaRepository<Book, Long> {
// Тут можна додавати кастомні методи за потреби
Book findByTitle(String title);
}
Коротке пояснення
- Розширюючи інтерфейс
JpaRepository, ми автоматично отримуємо всі стандартні методи, такі якsave(),findById(),deleteById()та інші. - У репозиторії ми також додали кастомний метод
findByTitle(), який виконує пошук книг за назвою.
Крок 5: Створення сервісу BookService
Сервісний шар відповідає за бізнес-логіку. Тут будемо використовувати наш репозиторій для керування даними.
package com.example.librarymanagement.service;
import com.example.librarymanagement.entity.Book;
import com.example.librarymanagement.repository.BookRepository;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BookService {
private final BookRepository bookRepository;
public BookService(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
public List<Book> getAllBooks() {
return bookRepository.findAll();
}
public Book getBookById(Long id) {
return bookRepository.findById(id).orElseThrow(() -> new RuntimeException("Книга не знайдена"));
}
public Book createBook(Book book) {
return bookRepository.save(book);
}
public void deleteBook(Long id) {
bookRepository.deleteById(id);
}
}
Крок 6: Створення контролера BookController
Контролер буде обробляти HTTP-запити і повертати дані клієнту.
package com.example.librarymanagement.controller;
import com.example.librarymanagement.entity.Book;
import com.example.librarymanagement.service.BookService;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/books")
public class BookController {
private final BookService bookService;
public BookController(BookService bookService) {
this.bookService = bookService;
}
@GetMapping
public List<Book> getAllBooks() {
return bookService.getAllBooks();
}
@GetMapping("/{id}")
public Book getBookById(@PathVariable Long id) {
return bookService.getBookById(id);
}
@PostMapping
public Book createBook(@RequestBody Book book) {
return bookService.createBook(book);
}
@DeleteMapping("/{id}")
public void deleteBook(@PathVariable Long id) {
bookService.deleteBook(id);
}
}
- Анотація
@RestControllerвказує, що це контролер для REST API. - Методи, такі як
getAllBooks()іcreateBook(), обробляють відповідні HTTP-запити (GET,POSTтощо). - Анотація
@RequestBodyдозволяє приймати об'єктBookз тіла HTTP-запиту.
Крок 7: Перевірка роботи
Через Postman, Curl або браузер виконай такі дії:
1. Надішли POST-запит на http://localhost:8080/api/books з тілом:
{
"title": "Effective Java",
"author": "Joshua Bloch",
"yearPublished": 2018
}
2. Отримай усі додані книги через GET:
curl -X GET http://localhost:8080/api/books
Підсумок
Ми успішно створили таблицю за допомогою JPA-сутності, реалізували репозиторій, додали бізнес-логіку у вигляді сервісу і створили контролер для обробки запитів. Тепер наш додаток готовий до роботи з базою даних: можемо додавати, читати і видаляти книги. У наступних лекціях розглянемо більш складні аспекти роботи з даними, такі як JPQL і ледаче/жадібне завантаження даних.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ