Мир баз данных опирается на язык структурированных запросов. Этот язык программирования предназначен для управления реляционными данными (извлечение, вставка, обновление и удаление), а его синтаксис является таблично-ориентированным. Вы можете осуществлять выборку столбцов из таблицы, состоящей из строк, соединять таблицы, комбинировать результаты двух SQL-запросов посредством объединений и т. д. Здесь нет объектов, а есть только строки, столбцы и таблицы. В мире Java, где мы манипулируем объектами, язык, созданный для работы с таблицами (SQL), необходимо «изогнуть» таким образом, чтобы он сочетался с языком, который базируется на объектах (Java). Именно здесь в дело вступает язык запросов Java Persistence Query Language.
JPQL — это язык, определенный в JPA для выполнения запросов к сущностям, которые располагаются в реляционных базах данных. Синтаксис JPQL похож на синтаксис SQL, однако используется в отношении объектов-сущностей, а не взаимодействует непосредственно с таблицами баз данных. JPQL не видит структуры основной базы данных и не имеет дела с таблицами или столбцами, а работает с объектами и атрибутами. Для этого он задействует точечную (.) нотацию, которая знакома Java-разработчикам.
Из этой главы вы узнаете, как управлять постоянными объектами. Это означает, что вы научитесь проводить операции создания, чтения, обновления и удаления (CRUD) с помощью менеджера сущностей, а также выполнять комплексные запросы с использованием JPQL. В этой главе также рассказывается о том, как JPA справляется с конкурентным доступом и работает с кэшем второго уровня. Она заканчивается объяснением жизненного цикла сущности и того, как JPA позволяет вам добавлять собственную бизнес-логику, когда в случае с сущностью имеют место определенные события.
Менеджер сущностей
Менеджер сущностей — центральный элемент JPA. Он управляет состоянием и жизненным циклом сущностей, а также позволяет выполнять запросы к сущностям в контексте постоянства. Менеджер сущностей отвечает за создание и удаление экземпляров постоянных сущностей и поиск сущностей по их первичному ключу. Он может блокировать сущности для защиты от конкурентного доступа, используя оптимистическую или пессимистическую блокировку, а также способен задействовать JPQL-запросы для извлечения сущностей согласно определенным критериям.
Когда менеджер сущностей получает ссылку на сущность, считается, что он управляет ею. До этого момента сущность рассматривается как обычный POJO-объект (то есть отсоединенный). Мощь JPA заключается в том, что сущности могут использоваться как обычные объекты на разных уровнях приложения и стать управляемыми менеджером сущностей, когда вам необходимо загрузить или вставить информацию в базу данных. Когда сущность находится под управлением, вы можете проводить операции, направленные на обеспечение постоянства, а менеджер сущностей будет автоматически синхронизировать состояние сущности с базой данных. Когда сущность оказывается отсоединенной (то есть не находится под управлением), она снова становится простым Java-объектом, который затем может быть использован на других уровнях (например, JavaServer Faces или JSF на уровне представления) без синхронизации его состояния с базой данных.
Что касается постоянства, то реальная работа здесь начинается с помощью менеджера сущностей. Он является интерфейсом, реализуемым поставщиком постоянства, который будет генерировать и выполнять SQL-операторы. Интерфейс javax.persistence.EntityManager представляет собой API-интерфейс для манипулирования сущностями (соответствующее подмножество приведено в листинге 6.1).
public interface EntityManager {
··// EntityManagerFactory для создания EntityManager,
··// его закрытия и проверки того, открыт ли он
··EntityManagerFactory getEntityManagerFactory();
··void close();
··boolean isOpen();
··// Возвращает EntityTransaction
··EntityTransaction getTransaction();
··// Обеспечивает постоянство, слияние сущности в базе данных,
··// а также ее удаление оттуда
··void persist(Object entity);
··
··void remove(Object entity);
··// Обеспечивает поиск сущности на основе ее первичного ключа
··// (с разными механизмами блокировки)
··