Embedded объекты

advertisement
ORM. Расширенные темы
1
Embedded объекты
 Embedded объект – это объект, который не имеет
собственной identity, а зависит от другой сущности
 В табличном представлении сама сущность и ее
embedded сущность представляют одну строку таблицы.
Физически не разделены
 Embedded сущности нужны, когда логически данные
представляют собой отношение, а не просто коллекцию
атрибутов, но БД хранит их физически в одной записи, по
той или иной причине
2
Пример. Embedded объекты
3
Embedded объекты
 Embedded сущность помечается аннотацией @Embeddable
 Embeddable сущность может содержать простые мэпинги:
@Basic, @Temporal, @Enumerated, @Lob и @Column
 Embeddable сущность не может содержать мэпинги
отношений
 Embedded сущность определяется в целевой сущности с
помощью @Embedded
 При работе с целевой сущностью, провайдер опрашивает
поля embedded сущности так, как будто эти поля
определены на целевой сущности
 Необходимо рассмотреть возможность переопределения
embedded сущности в обычную сущность, если модель
данных допускает модификацию
4
Пример. Embedded объекты
5
Совместное использование Embedded объектов
 Возможна ситуация, когда две или более сущностей
используют одинаковый embedded объект
 Так же возможна ситуация логически эквивалентных
embedded объектов, но соответствующие им колонки
таблиц физически имеют разные названия
6
Совместное использование Embedded объектов
 Можно использовать аннотацию @AttributeOverride,
чтобы переопределить поле(я) embedded сущности
 При совместном использовании embedded сущности
(класса) будет создано соответствующее количество
экземпляров этого класса
7
Пример. Совместное использование Embedded объектов
8
Составной первичный ключ
 Первичный ключ таблицы БД использует несколько
колонок. Распространено в legacy БД
 Необходимо создать дополнительный primary key класс
 Primary key класс должен:
 Быть public и имплементировать Serializable
 корректно переопределить методы equals() и
hashCode()
 Иметь конструктор без параметров
9
Составной первичный ключ. Id класс
 Одним из видов primary key класса является Id класс
Пример. Составной первичный ключ. Id класс (example_09-01)
 Primary key класс должен содержать атрибуты,
совпадающие (по имени и типу) с primary key атрибутами
целевой сущности
 Primary key класс может не иметь setter’ов. Провайдер
установит поля один раз через reflection
 Primary key класс является удобной абстракцией ключа:
10
Составной первичный ключ. Embedded Id класс
 В качестве primary key класса может выступать embedded
класс
 В этом случае embedded класс в целевой сущности
аннотируется с помощью @EmbeddedId
Пример. Составной первичный ключ. Embedded Id класс (example_09-02)
 В запросах можно указывать путь, переходящий на поля
embedded id класса, используя идентификатор id:
11
Read-only мэпинги
 JPA позволяет установить insertable и updatable
свойства на индивидуальные поля состояния (@Column) и
поля отношений (@JoinColumn)
 Можно установить значение false для insertable и/или
updatable, в предположении, что данные уже существуют
в БД
 Поля являются writable в памяти. Они не будут записаны
в БД при flush сущности
12
Пример. Read-only мэпинги
13
Опциональность
 Можно указать провайдеру на опциональноть полей или
single-valued ассоциаций
 Они могут быть null в БД
 На них не будет наложен not null constraint при генерации
схемы
 Элемент optional может быть указан для:
 @Basic
 @ManyToOne
 @OneToOne
 По умолчанию optional имеет значение true. Можно
указать false
14
Пример. Опциональность
15
Отношения. Расширенные темы
 В случае, когда объектная модель может диктовать схему
БД, сложные мэпинги не понадобятся
 В случае, когда БД уже существует и ее схему менять
нельзя, необходимо иметь возможность не
«стандартного» мэпинга
16
Составные join колонки
 В случае наличия compound ключа, может возникнуть
возможность ссылки на него
 Аннотация @JoinColumns служит для хранения
нескольких join колонок
 Таблица EMPLOYEE с compound ключом, ссылающимся на
себя
17
Пример. Составные join колонки
18
Идентификаторы, которые включают отношение
 Возможно иметь compound ключ, который включает
отношение. Этим подразумевается, что объект не может
существовать без другого, являющегося частью
идентификатора
 Используем primary key класс
 @JoinColumn ссылается на колонку, уже являющуюся
частью первичного ключа
Пример. Идентификаторы, которые включают отношение (example_09-03)
19
Мэпинг состояния отношения (Relationship state)
 В примере дату начала работы сотрудника над проектом
нельзя хранить ни в employee, ни в project, так как имеем
отношение many-to-many
 В БД все просто:
20
Мэпинг состояния отношения (Relationship state)
 В Java состояние определяется как обычный мэпинг
 Объект состояния будет иметь Many-to-one мэпинг на
целевые сущности (проект и работник)
 Первичный ключ объекта состояния будет compound,
состоящий из двух отношений на целевые сущности
Пример. Mapping Relationship state (example_09-04)
21
Несколько таблиц
 До сих пор мы рассматривали мэпинги, когда сущность
мэпилась на один ряд одной таблицы!
 Это не всегда так в legacy БД, где логически связанные
данные могут размещаться в разных рядах разных таблиц
(по разным причинам)
 Таблица, для которой соответствующая сущность,
аннотирована @Table называется primary table
 Таблица(ы), которой соответствуют связанные сущности,
называется secondary table(s)
22
Несколько таблиц
 Сущность аннотируется @SecondaryTable
 Когда часть данных primary сущности лежит в secondary
сущности, необходимо указать эту secondary сущность в
элементе table аннотаций @Column и @JoinColumn
 Для связывания primary таблицы и secondary таблиц, в
аннотации @SecondaryTable служит аннотация
@PrimaryKeyJoinColumn
 Поддержка для связывания secondary таблиц
ограничивается объединением первичного и вторичного
ключей
23
Пример. Несколько таблиц
24
Пример. Несколько таблиц
25
Обзорный пример. Несколько таблиц.
26
Наследование
 Очень часто при ОО дизайне наследование используется
неправильно – лишь для того, чтобы повторно
использовать несколько методов
 О особой осторожностью необходимо использовать
отношения наследования при O-R мэпинге
27
Пример. Наследование
28
Mapped супер класс
 JPA позволяет указывать mapped супер класс – класс
 не являющийся сущностью
 относительно него нельзя выполнять запросы
 он не может быть target сущностью
 Mapped супер класс может быть абстрактным или
конкретным. Рекомендуется делать его абстрактным
 Mapped супер класс определяет часть состояния, которое
недоступно непосредственно, но доступно сущностям,
являющимся подклассами
 Mapped супер класс аннотируется @MappedSuperclass
29
Пример. Mapped супер класс
30
Transient классы в иерархии
 Класс в иерархии, не являющийся ни сущностью, ни
mapped супер классом называется transient классом
 Состояние transient класса будет доступно подклассу
(сущности или mapped супер классу), но это состояние не
будет частью persistent состояния
 Transient класс удобно иметь для хранения временного
состояния, промежуточных вычислений и т.п.
31
Пример. Transient классы в иерархии
32
Абстрактные и конкретные класс
 Сущность, mapped супер класс и transient класс могут
быть абстрактными или конкретными
 Best practice делать mapped супер класс и transient
абстрактными
 Делать абстрактной сущность может быть разумно, в
случае, если данная сущность явно не используется в
приложении, а используются ее подклассы
 Можно успешно выполнять JPQL запросы для абстрактной
сущности – результатом будет набор сущностей,
представляющих подклассы
33
Модели наследования
 JPA поддерживает 3 модели наследования
 Когда существует иерархия, она обязана иметь корневую
сущность
 Корневая сущность аннотируется с помощью аннотации
@Inheritance, в качестве атрибута которой указывается
тип модели наследования
34
Стратегия Single-Table
 Наиболее распространенная и быстрая схема
 Набор полей всех подклассов хранится в одной строке
одной таблицы
 В строке содержатся параметры, значимые в контексте
одного подкласса, и бессмысленные в контексте другого
 Это означает, что некоторые колонки строки будут
незаполненными
 Первичный ключ указывается в корневой сущности и
наследуется подклассами
 Стратегия Single-Table является стратегией по умолчанию
и определяется с помощью
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
35
Стратегия Single-Table. Discriminator Column
 Специальная колонка, не участвующая в мэпинге,
служащая для разделения иерархии, называется
discriminator column
 Обозначается аннотацией @DiscriminatorColumn с
указанием имени discriminator колонки. По умолчанию
имя DTYPE
 Элемент discriminatorType определяет тип колонки:
 String (по умолчанию)
 Integer
 Char
36
Стратегия Single-Table. Discriminator Value
 Каждый ряд таблицы должен иметь значение, в
discriminator колонке, называемое discriminator value
или индикатор класса
 Соответствующее значение должно быть указано на
классе в иерархии, с помощью @DiscriminatorValue
 По умолчанию в качестве discriminator value используется
имя сущности
 Discriminator value может указываться только на
конкретных сущностях
37
Пример. Стратегия Single-Table.
 Скриншот 193
38
Пример. Стратегия Single-Table.
39
Joined стратегия
 С точки зрения OO дизайна, разумно использовать
отдельную таблицу для каждого класса в иерархии
 Хорошо нормализованная БД и хорошо
декомпозированная ОО модель подходят под эту
парадигму, но необходимо объединять таблицы. Такая
стратегия называется Joined Strategy
 Однако, возможна потеря производительности
 Для связывания secondary таблиц используется foreign
ключ, являющийся первичным ключом primary таблицы
40
Joined стратегия
 Необходимо явно указать стратегию
@Inheritance(strategy=InheritanceType.JOINED)
 Discriminator колонка по-прежнему необходима
41
Пример. Joined стратегия
 С 194 скриншот
42
Стратегия одна таблица на одну сущность
 Такая модель данных как правило будет означать
дублирование данных и не нормализованную БД
 Данная стратегия потребуется в будущих релизах JPA, в
данном релизе малопригодна

Пример. Стратегия одна таблица на одну сущность (example 09-01)
43
Download