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

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

Выборка связей

Все аннотации, которые вы видели ранее (@OneToOne, @OneToMany, @ManyToOne и @ManyToMany), определяют атрибут выборки, указывающий, что загрузка ассоциированных объектов должна быть незамедлительной или отложенной с результирующим влиянием на производительность. В зависимости от вашего приложения доступ к одним связям осуществляется чаще, чем к другим. В таких ситуациях вы можете оптимизировать производительность, загружая информацию из базы данных, когда сущность подвергается первоначальному чтению (незамедлительная загрузка) или когда к ней осуществляется доступ (отложенная загрузка). В качестве примера взглянем на некоторые крайние случаи.

Представим себе четыре сущности, которые все связаны между собой и имеют разные отношения («один к одному», «один ко многим»). В первом случае (рис. 5.19) между всеми сущностями будут связи EAGER. Это означает, что, как только вы загрузите Class1 (произведя поиск по идентификатору или выполнив запрос), все зависимые объекты будут автоматически загружены в память. Это может отразиться на производительности вашей системы.


Рис. 5.19. Четыре сущности со связями EAGER


Если взять противоположный сценарий, то все связи будут задействовать режим fetch, обеспечивающий отложенную выборку (рис. 5.20). При загрузке Class1 ничего больше загружаться не будет (за исключением, конечно же, непосредственных атрибутов Class1). Вам потребуется явным образом получить доступ к Class2 (например, с помощью метода-геттера), чтобы дать команду поставщику постоянства на загрузку информации из базы данных и т. д. Если вы захотите управлять всем графом объекта, то вам потребуется явным образом вызывать каждую сущность.


Рис. 5.20. Четыре сущности со связями LAZY


Однако не следует думать, что EAGER — это плохо, а LAZY — хорошо. EAGER поместит все данные в память с помощью небольшого количества операций доступа к базе данных (поставщик постоянства, вероятно, будет использовать запросы с соединением для связи таблиц и извлечения данных). В случае с LAZY вы не рискуете заполнить всю используемую вами память, поскольку будете контролировать, какой объект будет загружаться. Однако вам придется каждый раз осуществлять доступ к базе данных.

Параметр fetch очень важен, поскольку, если его неправильно использовать, это может привести к проблемам с производительностью. У каждой аннотации есть значение fetch по умолчанию, которое вам необходимо знать, и, если оно окажется неподходящим, изменить его (табл. 5.2).


Таблица 5.2. Стратегии выборки по умолчанию
АннотацияСтратегия выборки по умолчанию
@OneToOneEAGER
@ManyToOneEAGER
@OneToManyLAZY
@ManyToManyLAZY

Если при разгрузке заказа вам постоянно будет нужен доступ к его строкам в вашем приложении, то, возможно, будет целесообразно изменить режим fetch по умолчанию аннотации @OneToMany на EAGER (листинг 5.49).


Листинг 5.49. Order со связью EAGER с OrderLine

>@Entity

>public class Order {

>··@Id @GeneratedValue

>··private Long id;

>··@Temporal(TemporalType.TIMESTAMP)

>··private Date creationDate;

>··@OneToMany(fetch = FetchType.EAGER)

>··private List orderLines;

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

>}

Упорядочение связей

При связях «один ко многим» или «многие ко многим» ваши сущности имеют дело с коллекциями объектов. На стороне Java эти коллекции обычно неупорядочены. В таблицах реляционных баз данных тоже не соблюдается какой-либо порядок. Следовательно, если у вас возникнет необходимость в упорядоченном списке, то вам придется либо отсортировать свою коллекцию программным путем, либо воспользоваться JPQL-запросом с предложением ORDER BY. У JPA имеются более простые механизмы, основанные на аннотациях, которые могут помочь в упорядочении связей.


@OrderBy

Динамическое упорядочение может быть обеспечено благодаря аннотации @OrderBy. «Динамическое» оно потому, что вы упорядочиваете элементы коллекции при извлечении ассоциации.

В примере приложения CD-BookStore пользователям предоставляется возможность писать новости о музыке и книгах. Эти новости затем выкладываются на сайте, а после их публикации люди могут добавлять к ним комментарии (листинг 5.50). Вам необходимо, чтобы комментарии выводились на сайте в хронологическом порядке.


Листинг 5.50. Сущность Comment с postedDate

>@Entity

>public class Comment {

>··@Id @GeneratedValue

>··private Long id;

>··private String nickname;

>··private String content;

>··private Integer note;

>··@Column(name = "posted_date")

>··@Temporal(TemporalType.TIMESTAMP)

>··private Date postedDate;

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

>}

Комментарии моделируются с использованием сущности Comment, показанной в листинге 5.50. У нее имеется content, она размещается пользователем (идентифицируется параметром nickname), оставляющим примечания к новостям, кроме того, она располагает postedDate типа TIMESTAMP, который автоматически создается системой. В случае с сущностью News, показанной в листинге 5.51, вы захотите иметь возможность упорядочивать список комментариев согласно дате их размещения в убывающем порядке. Для этого вам потребуется прибегнуть к аннотации @OrderBy в сочетании с аннотацией @OneToMany.


Рекомендуем почитать
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 так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.