JavaRush /Курси /Модуль 5. Spring /Практика: створення таблиць і запитів у базі даних за доп...

Практика: створення таблиць і запитів у базі даних за допомогою JPA

Модуль 5. Spring
Рівень 5 , Лекція 7
Відкрита

Сьогодні ми зробимо повноцінний додаток на 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 і ледаче/жадібне завантаження даних.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ