Продолжим изучение Spring в углубленных статьях.
Объектно-реляционное отображение (ORM - Object-Relational Mapping)
1. Что такое ORM?
ORM (Object-Relational Mapping) — это технология, которая позволяет программам работать с реляционной базой данных, используя объектно-ориентированный подход. Она автоматически преобразует объекты языка программирования (например, Java-классы) в строки таблиц базы данных и обратно.
Основные задачи ORM:
Автоматическое сопоставление объектов с таблицами базы данных.
Управление состояниями объектов (создание, обновление, удаление, чтение).
Оптимизация работы с БД за счёт кеширования и ленивой загрузки.
Генерация SQL-запросов без необходимости их явного написания.
2. Как работает ORM?
Работа ORM состоит из нескольких ключевых этапов:
2.1. Анализ классов сущностей
При запуске приложения ORM-провайдер анализирует классы, помеченные аннотациями (например, @Entity в JPA/Hibernate), и строит их соответствие с таблицами базы данных.
Пример класса-сущности:
ORM анализирует этот класс и определяет:
Таблица называется users.
Поле id — первичный ключ с автоинкрементом.
Поле username обязательно (nullable = false).
Поле email должно быть уникальным.
2.2. Генерация SQL-запросов
При выполнении операций с объектами ORM автоматически генерирует SQL-запросы.
Например:
Этот код сгенерирует SQL-запрос:
Если позже мы изменим объект и сохраним его, ORM выполнит UPDATE:
2.3. Управление состояниями объектов
Каждый объект, управляемый ORM, может находиться в одном из четырёх состояний:
Transient - Объект создан, но не сохранён в БД.
Managed - Объект привязан к контексту EntityManager.
Detached - Объект был сохранён, но теперь отсоединён.
Removed - Объект помечен для удаления.
Пример:
2.4. Кеширование
ORM использует кеширование для уменьшения нагрузки на базу данных.
Первичный кеш (L1 Cache): Внутри EntityManager. Если объект уже загружен, он не запрашивается заново.
Вторичный кеш (L2 Cache): Глобальный кеш, доступный для всех EntityManager.
Пример:
2.5. Ленивые (Lazy) и Жадные (Eager) загрузки
ORM позволяет загружать связанные данные жадно (EAGER) или лениво (LAZY).
Пример:
LAZY — данные загружаются только при обращении к orders.
EAGER — данные загружаются сразу при запросе User.
3. Виды ORM и их отличия
3.1. Полноценные ORM (с динамическим SQL)
Автоматически генерируют SQL-запросы и управляют объектами:
Hibernate (Spring Data JPA)
EclipseLink
TopLink
3.2. Полу-ORM (с маппингом, но без генерации SQL)
Работают с SQL, но помогают преобразовывать результаты в объекты:
MyBatis (требует явного написания SQL)
3.3. Lightweight ORM (обёртки над JDBC)
Spring JdbcTemplate — облегчённая обёртка над JDBC, но без автоматического маппинга.
#Java #Training #Spring #SpringDataJPA #ORM
Объектно-реляционное отображение (ORM - Object-Relational Mapping)
1. Что такое ORM?
ORM (Object-Relational Mapping) — это технология, которая позволяет программам работать с реляционной базой данных, используя объектно-ориентированный подход. Она автоматически преобразует объекты языка программирования (например, Java-классы) в строки таблиц базы данных и обратно.
Основные задачи ORM:
Автоматическое сопоставление объектов с таблицами базы данных.
Управление состояниями объектов (создание, обновление, удаление, чтение).
Оптимизация работы с БД за счёт кеширования и ленивой загрузки.
Генерация SQL-запросов без необходимости их явного написания.
2. Как работает ORM?
Работа ORM состоит из нескольких ключевых этапов:
2.1. Анализ классов сущностей
При запуске приложения ORM-провайдер анализирует классы, помеченные аннотациями (например, @Entity в JPA/Hibernate), и строит их соответствие с таблицами базы данных.
Пример класса-сущности:
Редактировать
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "username", nullable = false)
private String username;
@Column(name = "email", unique = true)
private String email;
}
ORM анализирует этот класс и определяет:
Таблица называется users.
Поле id — первичный ключ с автоинкрементом.
Поле username обязательно (nullable = false).
Поле email должно быть уникальным.
2.2. Генерация SQL-запросов
При выполнении операций с объектами ORM автоматически генерирует SQL-запросы.
Например:
User user = new User();
user.setUsername("john_doe");
user.setEmail("john@example.com");
userRepository.save(user);
Этот код сгенерирует SQL-запрос:
INSERT INTO users (username, email) VALUES ('john_doe', 'john@example.com');
Если позже мы изменим объект и сохраним его, ORM выполнит UPDATE:
user.setEmail("new_email@example.com");
userRepository.save(user);
UPDATE users SET email = 'new_email@example.com' WHERE id = 1;
Разработчик не пишет SQL-код вручную — ORM делает это автоматически.
2.3. Управление состояниями объектов
Каждый объект, управляемый ORM, может находиться в одном из четырёх состояний:
Transient - Объект создан, но не сохранён в БД.
Managed - Объект привязан к контексту EntityManager.
Detached - Объект был сохранён, но теперь отсоединён.
Removed - Объект помечен для удаления.
Пример:
User user = new User(); // Transient
user.setUsername("Alice");
entityManager.persist(user); // Managed
entityManager.detach(user); // Detached
entityManager.remove(user); // Removed
2.4. Кеширование
ORM использует кеширование для уменьшения нагрузки на базу данных.
Первичный кеш (L1 Cache): Внутри EntityManager. Если объект уже загружен, он не запрашивается заново.
Вторичный кеш (L2 Cache): Глобальный кеш, доступный для всех EntityManager.
Пример:
User user1 = entityManager.find(User.class, 1); // SQL выполняется
User user2 = entityManager.find(User.class, 1); // Берётся из кеша
Первый запрос загрузит данные из БД, второй возьмёт их из памяти.
2.5. Ленивые (Lazy) и Жадные (Eager) загрузки
ORM позволяет загружать связанные данные жадно (EAGER) или лениво (LAZY).
Пример:
@Entity
public class User {
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private List<Order> orders;
}
LAZY — данные загружаются только при обращении к orders.
EAGER — данные загружаются сразу при запросе User.
User user = userRepository.findById(1L).get();
List<Order> orders = user.getOrders(); // SQL-запрос будет только здесь, если Lazy
3. Виды ORM и их отличия
3.1. Полноценные ORM (с динамическим SQL)
Автоматически генерируют SQL-запросы и управляют объектами:
Hibernate (Spring Data JPA)
EclipseLink
TopLink
3.2. Полу-ORM (с маппингом, но без генерации SQL)
Работают с SQL, но помогают преобразовывать результаты в объекты:
MyBatis (требует явного написания SQL)
3.3. Lightweight ORM (обёртки над JDBC)
Spring JdbcTemplate — облегчённая обёртка над JDBC, но без автоматического маппинга.
#Java #Training #Spring #SpringDataJPA #ORM