Найти в Дзене
Виски с кодом

Удивительные аннотации JPA, которые сделают вас мастером базы данных в Spring: Вы упускали самые важные возможности!

Аннотации JPA (Java Persistence API), используемые в Spring Boot @Entity:Описание: Аннотация, указывающая, что класс является сущностью базы данных. Объекты этого класса будут отображаться на таблицы базы данных.
Работа: При использовании этой аннотации класс становится сущностью JPA, что позволяет сохранять его экземпляры в базе данных. Пример: import javax.persistence.*;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String email;
// Геттеры и сеттеры
} @Table:Описание: Аннотация, указывающая дополнительные настройки для таблицы базы данных, связанной с сущностью.
Работа: Позволяет настраивать имя таблицы, используемые индексы, каталоги и другие атрибуты таблицы в базе данных. import javax.persistence.*;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;

Аннотации JPA (Java Persistence API), используемые в Spring Boot

@Entity:Описание: Аннотация, указывающая, что класс является сущностью базы данных. Объекты этого класса будут отображаться на таблицы базы данных.
Работа: При использовании этой аннотации класс становится сущностью JPA, что позволяет сохранять его экземпляры в базе данных.

Пример:

import javax.persistence.*;

@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String username;
private String email;

// Геттеры и сеттеры
}

@Table:Описание: Аннотация, указывающая дополнительные настройки для таблицы базы данных, связанной с сущностью.
Работа: Позволяет настраивать имя таблицы, используемые индексы, каталоги и другие атрибуты таблицы в базе данных.

import javax.persistence.*;

@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String username;
private String email;

// Геттеры и сеттеры
}

@Id:Описание: Аннотация, указывающая поле, которое является первичным ключом сущности.
Работа: Определяет поле, которое будет использоваться в качестве идентификатора сущности в базе данных.

пример выше.

@GeneratedValue:Описание: Аннотация, указывающая, как должны генерироваться значения для первичных ключей.
Работа: Позволяет настроить стратегию генерации значений для первичных ключей, такие как автоматическое инкрементирование, использование последовательностей и т. д.

пример выше.

@Column:Описание: Аннотация, используемая для настройки свойств колонки базы данных, связанной с полем сущности.
Работа: Позволяет настраивать имя колонки, её тип данных, ограничения и другие атрибуты.

import javax.persistence.*;

@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "product_name", nullable = false)
private String name;

@Column(name = "product_price", precision = 10, scale = 2)
private double price;

// Геттеры и сеттеры
}

@ManyToOne / @OneToMany / @ManyToMany:Описание: Аннотации, указывающие на тип отношений между сущностями.
Работа: Определяют связи между сущностями, такие как многие к одному, один ко многим и многие ко многим соответственно.


import javax.persistence.*;
import java.util.List;

@Entity
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String title;
private String content;

@ManyToOne
private User author;

@OneToMany(mappedBy = "post")
private List<Comment> comments;

// Геттеры и сеттеры
}

@NamedQuery:Описание: Аннотация, позволяющая предопределить именованные запросы (JPQL) для сущности.
Работа: Позволяет создавать именованные JPQL запросы, которые можно использовать для выполнения операций на сущности без явного написания SQL.

Ссылка на подробное описание: https://thorben-janssen.com/spring-data-jpa-named-queries/

import javax.persistence.*;

@Entity
@NamedQuery(
name = "Product.findByName",
query = "SELECT p FROM Product p WHERE p.name = :name"
)
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String name;
private double price;

// Геттеры и сеттеры
}

@Transactional:Описание: Аннотация, указывающая, что метод должен быть выполнен в рамках транзакции.
Работа: Обеспечивает управление транзакциями на уровне метода, гарантируя целостность данных в базе данных.

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class ProductService {

private final ProductRepository productRepository;

public ProductService(ProductRepository productRepository) {
this.productRepository = productRepository;
}

@Transactional
public void saveProduct(Product product) {
productRepository.save(product);
}

@Transactional(readOnly = true)
public Product getProductById(Long productId) {
return productRepository.findById(productId).orElse(null);
}
}


В этом примере аннотация
@Transactional применяется к методам saveProduct() и getProductById(). Разные параметры аннотации используются в этих двух методах:

  1. Метод saveProduct(): Он помечен аннотацией @Transactional без параметров, что означает, что этот метод управляется транзакцией и может выполнять изменения в базе данных. При вызове этого метода, если транзакция еще не существует, она будет создана. По завершении метода транзакция будет закрыта, и изменения будут зафиксированы (если нет исключений).
  2. Метод getProductById(): Он также помечен аннотацией @Transactional, но с параметром readOnly = true. Этот параметр указывает, что метод только читает данные из базы данных и не выполняет изменений. При использовании readOnly = true транзакция будет оптимизирована для чтения данных, что может улучшить производительность.

Эти аннотации @Transactional управляют транзакциями на уровне методов сервиса, обеспечивая целостность данных в базе данных и контролируя их доступность для чтения и записи.

@Embeddable:Описание: Аннотация, указывающая, что класс является встраиваемым объектом, который может быть встроен в другие сущности.
Работа: Позволяет создавать переиспользуемые компоненты данных, которые могут быть встроены в несколько сущностей.

import javax.persistence.*;

@Embeddable
public class Address {
private String street;
private String city;
private String zipCode;

// Геттеры и сеттеры
}

@Embedded:Описание: Аннотация, указывающая, что поле должно быть встроено в сущность.
Работа: Позволяет встраивать объекты, отмеченные аннотацией @Embeddable, в текущую сущность.

import javax.persistence.*;

@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String username;

@Embedded
private Address address;

// Геттеры и сеттеры
}

@Transient:Описание: Аннотация, указывающая, что поле или метод не должны быть сохранены в базе данных.
Работа: Помечает поле или метод как временные, то есть данные не будут сохраняться в базе данных при сохранении сущности.

import javax.persistence.*;

@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String name;
private double price;

@Transient
private double discountPrice;

// Геттеры и сеттеры
}

@Version:Описание: Аннотация, указывающая поле, которое будет использоваться для отслеживания версии сущности для оптимистической блокировки.
Работа: Позволяет JPA автоматически увеличивать версию сущности при каждом изменении, что используется для обнаружения конфликтов изменений при параллельных обновлениях.

import javax.persistence.*;

@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String name;
private double price;

@Version
private int version;

// Геттеры и сеттеры
}

@IdClass:Описание: Аннотация, указывающая класс, который содержит составной ключ для сущности.
Работа: Позволяет определить составной ключ, используемый для идентификации сущности, когда ключ состоит из нескольких полей.

import javax.persistence.*;

@Entity
@IdClass(UserId.class)
public class User {
@Id
private Long userId;

@Id
private String username;

// Геттеры и сеттеры
}

public class UserId implements Serializable {
private Long userId;
private String username;

// Геттеры и сеттеры
}

@MappedSuperclass:Описание: Аннотация, указывающая, что класс является базовым классом для других сущностей, но сам по себе не является сущностью.
Работа: Позволяет создавать общие поля и методы, которые будут унаследованы другими сущностями, которые расширяют этот класс.

import javax.persistence.*;

@MappedSuperclass
public abstract class BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

// Геттеры и сеттеры
}

@Inheritance:Описание: Аннотация, указывающая стратегию наследования для сущности.
Работа: Позволяет настроить стратегию наследования, такую как одна таблица для всех подклассов (SINGLE_TABLE), таблица для каждого подкласса (TABLE_PER_CLASS) или таблица для каждого класса (JOINED).

import javax.persistence.*;

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "user_type")
public abstract class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String username;

// Геттеры и сеттеры
}

@Entity
@DiscriminatorValue("ADMIN")
public class AdminUser extends User {
// Дополнительные поля и методы для администратора
}

@Entity
@DiscriminatorValue("REGULAR")
public class RegularUser extends User {
// Дополнительные поля и методы для обычного пользователя
}

@SequenceGenerator:Описание: Аннотация, которая определяет настройки генератора последовательностей для генерации значений первичных ключей.
Работа: Позволяет настроить параметры генератора последовательностей, такие как имя последовательности, начальное значение, приращение и т.д.


import javax.persistence.*;

@Entity
@Table(name = "employees")
@SequenceGenerator(name = "employee_seq", sequenceName = "employee_sequence", allocationSize = 1)
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "employee_seq")
private Long id;

private String name;
private String department;

// Геттеры и сеттеры
}

@TableGenerator:Описание: Аннотация, которая определяет настройки генератора таблиц для генерации значений первичных ключей.
Работа: Позволяет настроить параметры генератора таблиц, такие как имя таблицы, имя столбца, начальное значение, приращение и т.д.


import javax.persistence.*;

@Entity
@Table(name = "employees")
@TableGenerator(name = "emp_gen", table = "id_gen", pkColumnName = "gen_name", valueColumnName = "gen_val", allocationSize = 1)
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "emp_gen")
private Long id;

private String name;
private String department;

// Геттеры и сеттеры
}

@JoinTable:Описание: Аннотация, которая используется для настройки таблицы соединений для связи многие ко многим.
Работа: Позволяет настроить имя таблицы соединений, а также столбцы, используемые для соединения двух таблиц.

import javax.persistence.*;
import java.util.Set;

@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String name;

@ManyToMany
@JoinTable(
name = "student_course",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id")
)
private Set<Course> courses;

// Геттеры и сеттеры
}

@JoinColumn:Описание: Аннотация, которая используется для настройки столбца внешнего ключа, используемого для связи между таблицами.
Работа: Позволяет настроить имя столбца внешнего ключа, а также его свойства, такие как уникальность, nullable и др.

import javax.persistence.*;

@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String title;

@ManyToOne
@JoinColumn(name = "author_id")
private Author author;

// Геттеры и сеттеры
}

@Enumerated:Описание: Аннотация, которая используется для отображения перечислений в базе данных.
Работа: Позволяет настроить способ отображения перечислений в базе данных, например, как строку или как число.

import javax.persistence.*;

@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String name;

@Enumerated(EnumType.STRING)
private ProductType type;

// Геттеры и сеттеры
}

public enum ProductType {
ELECTRONICS,
CLOTHING,
BOOKS
}

@Temporal:Описание: Аннотация, которая указывает, как отображать даты и времена в базе данных.
Работа: Позволяет настроить способ хранения даты и времени в базе данных, такие как DATE, TIME или TIMESTAMP.

import javax.persistence.*;
import java.util.Date;

@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String name;

@Temporal(TemporalType.DATE)
private Date hireDate;

// Геттеры и сеттеры
}

@Formula:Описание: Аннотация, которая позволяет определить вычисляемое значение столбца, которое не хранится в базе данных.
Работа: Позволяет указать SQL-выражение, которое будет вычисляться при запросе, но не храниться в базе данных.

import javax.persistence.*;

@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String name;
private int salary;

@Formula("salary * 0.1")
private int bonus;

// Геттеры и сеттеры
}