1. Архітектурний підхід: Від JDBC до Spring Data

У класичному Java-світі ми працювали безпосередньо з SQL. Це давало контроль, але породжувало багато помилок. Потім з'явився Hibernate (ORM-фреймворк), який дозволив мислити об'єктами. Spring Data JPA — це ще вищий рівень абстракції, який «ховає» складність Hibernate під капот.
Основні компоненти стеку:
  • Database: Місце зберігання (PostgreSQL, MySQL, H2).
  • DataSource: Пул з'єднань до бази.
  • JPA (Java Persistence API): Стандарт/специфікація.
  • Hibernate: Реалізація JPA.
  • Spring Data JPA: Магія, яка генерує запити за назвою методу.

2. Створення сутності (Entity)

Entity — це ваш Java-клас, який «дзеркалить» таблицю в базі. Кожен екземпляр класу — це рядок у таблиці.
@Entity
@Table(name = "users") // Назва таблиці в БД
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "user_name", nullable = false, length = 100)
    private String name;

    @Column(unique = true)
    private String email;

    @Transient
    private String tempToken; // Це поле не буде збережене в БД

    // Геттери, сеттери, конструктори
}
Ключові деталі:
  • @Id — обов'язковий первинний ключ.
  • @GeneratedValue — база сама призначає ID (автоінкремент).
  • @Transient — використовуйте для полів, які потрібні лише в пам'яті програми.

3. Репозиторії: Прощавай, шаблонний код

Найсильніша сторона Spring Data — інтерфейс JpaRepository. Вам не потрібно писати реалізацію. Spring зробить це за вас.
public interface UserRepository extends JpaRepository<User, Long> {

    // Автоматично: SELECT * FROM users WHERE email = ?
    Optional<User> findByEmail(String email);

    // Складніший фільтр: SELECT * FROM users WHERE name LIKE ? AND email LIKE ?
    List<User> findByNameContainingAndEmailContaining(String name, String email);

    @Query("SELECT u FROM User u WHERE u.email LIKE %:domain")
    List<User> findUsersByEmailDomain(@Param("domain") String domain);
}
Ви отримуєте методи save(), findAll(), findById(), deleteById() просто «з коробки».

4. Зв'язки між таблицями

Реальний світ складний, тому об'єкти пов'язані між собою.
  • ManyToOne (Багато до одного): Найчастіший зв'язок. Багато співробітників в одному департаменті.
  • OneToMany (Один до багатьох): Зворотний бік.
@Entity
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "customer_id")
    private Customer customer;
}
⚡ Важливо про FetchType:
  • LAZY — завантажує пов'язаний об'єкт тільки тоді, коли ви до нього звернетесь (через getCustomer()). Це економить ресурси.
  • EAGER — завантажує все одразу. Використовуйте обережно, щоб не «покласти» базу великими запитами.

5. Транзакційність

Що, якщо ви переказуєте гроші з одного рахунку на інший? Ви знімаєте гроші в одного (Update) і додаєте іншому (Update). Якщо після першого кроку вимкнеться світло — гроші зникнуть.
Анотація @Transactional гарантує: або обидві дії успішні, або (якщо сталася помилка) база повернеться до початкового стану (Rollback).
@Service
public class BankService {

    @Transactional
    public void transferMoney(Long fromId, Long toId, Double amount) {
        accountRepository.withdraw(fromId, amount);
        // Якщо тут виникне RuntimeException, withdraw скасується автоматично
        accountRepository.deposit(toId, amount);
    }
}

6. Життєвий цикл Entity (Persistence Context)

Hibernate не просто відправляє SQL. Він стежить за об'єктами в «контексті».
  1. Transient: Об'єкт створено (new User()), але база про нього не знає.
  2. Managed: Об'єкт у базі, і Hibernate стежить за кожною його зміною.
  3. Detached: Об'єкт був у базі, але сесія закрита. Зміни в ньому більше не синхронізуються автоматично.
  4. Removed: Об'єкт помічений на видалення.

🛠️ Практична порада

При налаштуванні application.properties завжди вмикайте логування SQL на етапі навчання:
spring.jpa.show-sql=true
Це дозволить вам бачити, які саме запити генерує Spring «під капотом».


Остання зміна: середа 20 травня 2026 12:07 PM