Мир баз данных опирается на язык структурированных запросов. Этот язык программирования предназначен для управления реляционными данными (извлечение, вставка, обновление и удаление), а его синтаксис является таблично-ориентированным. Вы можете осуществлять выборку столбцов из таблицы, состоящей из строк, соединять таблицы, комбинировать результаты двух SQL-запросов посредством объединений и т. д. Здесь нет объектов, а есть только строки, столбцы и таблицы. В мире Java, где мы манипулируем объектами, язык, созданный для работы с таблицами (SQL), необходимо «изогнуть» таким образом, чтобы он сочетался с языком, который базируется на объектах (Java). Именно здесь в дело вступает язык запросов Java Persistence Query Language.

JPQL — это язык, определенный в JPA для выполнения запросов к сущностям, которые располагаются в реляционных базах данных. Синтаксис JPQL похож на синтаксис SQL, однако используется в отношении объектов-сущностей, а не взаимодействует непосредственно с таблицами баз данных. JPQL не видит структуры основной базы данных и не имеет дела с таблицами или столбцами, а работает с объектами и атрибутами. Для этого он задействует точечную (.) нотацию, которая знакома Java-разработчикам.

Из этой главы вы узнаете, как управлять постоянными объектами. Это означает, что вы научитесь проводить операции создания, чтения, обновления и удаления (CRUD) с помощью менеджера сущностей, а также выполнять комплексные запросы с использованием JPQL. В этой главе также рассказывается о том, как JPA справляется с конкурентным доступом и работает с кэшем второго уровня. Она заканчивается объяснением жизненного цикла сущности и того, как JPA позволяет вам добавлять собственную бизнес-логику, когда в случае с сущностью имеют место определенные события.

<p>Менеджер сущностей</p>

Менеджер сущностей — центральный элемент JPA. Он управляет состоянием и жизненным циклом сущностей, а также позволяет выполнять запросы к сущностям в контексте постоянства. Менеджер сущностей отвечает за создание и удаление экземпляров постоянных сущностей и поиск сущностей по их первичному ключу. Он может блокировать сущности для защиты от конкурентного доступа, используя оптимистическую или пессимистическую блокировку, а также способен задействовать JPQL-запросы для извлечения сущностей согласно определенным критериям.

Когда менеджер сущностей получает ссылку на сущность, считается, что он управляет ею. До этого момента сущность рассматривается как обычный POJO-объект (то есть отсоединенный). Мощь JPA заключается в том, что сущности могут использоваться как обычные объекты на разных уровнях приложения и стать управляемыми менеджером сущностей, когда вам необходимо загрузить или вставить информацию в базу данных. Когда сущность находится под управлением, вы можете проводить операции, направленные на обеспечение постоянства, а менеджер сущностей будет автоматически синхронизировать состояние сущности с базой данных. Когда сущность оказывается отсоединенной (то есть не находится под управлением), она снова становится простым Java-объектом, который затем может быть использован на других уровнях (например, JavaServer Faces или JSF на уровне представления) без синхронизации его состояния с базой данных.

Что касается постоянства, то реальная работа здесь начинается с помощью менеджера сущностей. Он является интерфейсом, реализуемым поставщиком постоянства, который будет генерировать и выполнять SQL-операторы. Интерфейс javax.persistence.EntityManager представляет собой API-интерфейс для манипулирования сущностями (соответствующее подмножество приведено в листинге 6.1).

Листинг 6.1. Подмножество API-интерфейса EntityManager

public interface EntityManager {

··// EntityManagerFactory для создания EntityManager,

··// его закрытия и проверки того, открыт ли он

··EntityManagerFactory getEntityManagerFactory();

··void close();

··boolean isOpen();

··// Возвращает EntityTransaction

··EntityTransaction getTransaction();

··// Обеспечивает постоянство, слияние сущности в базе данных,

··// а также ее удаление оттуда

··void persist(Object entity);

·· T merge(T entity);

··void remove(Object entity);

··// Обеспечивает поиск сущности на основе ее первичного ключа

··// (с разными механизмами блокировки)

·· T find(Class entityClass, Object primaryKey);

Перейти на страницу:

Похожие книги