Изучаем Java EE 7 - [91]

Шрифт
Интервал

. Приводившиеся до сих пор примеры опирались на поведение каскадирования по умолчанию, а не на настроенное поведение. В листинге 6.17 показано, что для создания Customer нужно сгенерировать экземпляры сущностей Customer и Address, связать их (customer.setAddress(address)), а затем обеспечить постоянство этих двух экземпляров.


Листинг 6.17. Обеспечение постоянства Customer и Address

>Customer customer = new Customer("Энтони", "Балла", "[email protected]");

>Address address = new Address("Ризердаун Роуд", "Лондон", "8QE", "Англия");

>customer.setAddress(address);


>tx.begin();

>em.persist(customer);

>em.persist(address);

>tx.commit();

Поскольку между Customer и Address есть связь, вы могли бы каскадировать действие persist от Customer к Address. Это означало бы, что вызов em.persist(customer) привел бы к каскадированию события PERSIST к сущности Address, если она допускает распространение события такого типа. Тогда вы могли бы сократить код и избавиться от em.persist(address), как показано в листинге 6.18.


Листинг 6.18. Каскадирование события PERSIST к Address

>Customer customer = new Customer("Энтони", "Балла", "[email protected]");

>Address address = new Address("Ризердаун Роуд", "Лондон", "8QE", "Англия");

>customer.setAddress(address);


>tx.begin();

>em.persist(customer);

>tx.commit();

Без каскадирования было бы обеспечено постоянство Customer, но не Address. Каскадирование события возможно при изменении отображения связи. У аннотаций @OneToOne, @OneToMany, @ManyToOne и @ManyToMany есть атрибут cascade, который принимает массив событий для каскадирования, а также событие PERSIST, которое можно каскадировать, как и событие REMOVE (широко используемое для выполнения каскадных удалений). Для этого вам потребуется изменить отображение сущности Customer (листинг 6.19) и добавить атрибут cascade в аннотацию @OneToOne в случае с Address.


Листинг 6.19. Сущность Customer и каскадирование событий PERSIST и REMOVE

>@Entity

>public class Customer {

>@Id @GeneratedValue

>··private Long id;

>··private String firstName;

>··private String lastName;

>··private String email;

>··@OneToOne (fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.REMOVE})

>··@JoinColumn(name = "address_fk")

>··private Address address;

>··// Конструкторы, геттеры, сеттеры

>}

Вы можете выбирать из нескольких событий для каскадирования к цели ассоциации (эти события приведены в табл. 6.3) и даже каскадировать их все, используя тип CascadeType.ALL.


Таблица 6.3. Возможные события для каскадирования
CascadeTypeОписание
PERSISTКаскадирует операции по обеспечению постоянства к цели ассоциации
REMOVEКаскадирует операции удаления к цели ассоциации
MERGEКаскадирует операции объединения к цели ассоциации
REFRESHКаскадирует операции обновления к цели ассоциации
DETACHКаскадирует операции отсоединения к цели ассоциации
ALLОбъявляет, что должны быть каскадированы все предыдущие операции

JPQL

Вы только что видели, как манипулировать сущностями по отдельности, используя API-интерфейс EntityManager. Вы уже знаете, как искать сущность по идентификатору, удалять ее, обновлять ее атрибуты и т. д. Однако поиск сущности по идентификатору довольно сильно ограничивает вас, поскольку вы можете извлечь только одну сущность, используя ее уникальный идентификатор. На практике вам может потребоваться извлечь сущность, исходя из иных критериев (имени, ISBN-номера и т. д.), либо извлечь набор сущностей на основе других критериев (например, все сущности, связанные с клиентами, проживающими в США). Эта возможность присуща реляционным базам данных, а у JPA есть язык, который обеспечивает это взаимодействие, — JPQL.

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

«За кулисами» JPQL применяет механизм отображения для преобразования JPQL-запросов в такие, которые будут понятны базам данных SQL. Запрос выполняется в отношении основной базы данных с использованием SQL- и JDBC-вызовов, после чего следует присваивание значений атрибутам экземпляров сущностей и их возврат приложению — все происходит очень простым и эффективным образом с применением богатого синтаксиса запросов.

Самый простой JPQL-запрос обеспечивает выборку всех экземпляров одной сущности:

>SELECT b

>FROM Book b

Если вы знаете SQL, то этот код должен показаться вам знакомым. Вместо выборки из таблицы JPQL производит выборку сущностей, в данном случае той, что носит имя Book. Кроме того, используется оператор FROM для наделения сущности псевдонимом: b является псевдонимом Book. Оператор SELECT запроса указывает на то, что типом результата запроса является сущность b (Book). Выполнение этого оператора приведет к получению списка, в который будет входить нуль или более экземпляров Book.


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


MFC и OpenGL

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Симуляция частичной специализации

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Обработка событий в С++

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.