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 и ленивую/жадную загрузку данных.

Комментарии (2)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Артём Уровень 112
5 сентября 2025
Что-то лекции стали повторяться. :-)
Алексей Уровень 115
30 октября 2025
Повторение - мать учения.