Many-to-one мэпинг

Download Report

Transcript Many-to-one мэпинг

Объектно-реляционный мэпинг
1
Обзор

Аннотации. Виды аннотаций

Доступ к состоянию сущности

Мэпинг сущности на таблицу

Мэпинг простых типов

Мэпинг первичного ключа

Генерация первичных ключей

Отношения. Определения

Виды ассоциаций

Many-to-one мэпинг

One-to-one мэпинг

One-to-Many мэпинг

Many-to-Many мэпинг

Join таблица

Однонаправленные collection-valued мэпинги

Использование коллекций

Lazy загрузка
2
Аннотации
 Могут быть определены на уровне
 Класса
 Метода
 Поля
 Выделяются 2 логические группы
 Логические аннотации
 Физические аннотации
3
Доступ к состоянию сущности
 Аннотация может быть определена на:
 Поле
 Методе (провайдер будет использовать метод
по умолчанию)
 Для доступа используется механизм Java
Reflection
4
Аннотирование поля
 Модификатор доступа:
 protected, package, private. Не public
 Getter и Setter игнорируются
@Entity
public class Employee {
@Id
private int id;
//Не! Будет вызван провайдером
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
....
5
Аннотирование метода
 Аннотируется getter
 Видимость public или protected
 Setter обязан присутствовать
 Getter и setter должны удовлетворять соглашению JavaBeans
 Если аннотация не указана, getter (не поле) будет использован
провайдером
@Entity
public class Employee {
private int id;
private long wage;
@Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public long getSalary() {
return wage;
}
public void setSalary(long salary) {
this.wage = salary;
}
6
Мэпинг сущности на таблицу
 @Entity определяет сущность. Обязательное поле
 Название таблицы по умолчанию – имя класса
 @Table(name=“EMP”, schema=“HR”, catalog=“HR.EMP”
@Entity
@Table(name="EMP", schema="HR")
public class Employee {
…
}
7
Мэппинг простых типов
 Поля следующих типов могут быть persisted провайдером:
 Primitive Java types: byte, int, short, long, boolean, char, float, double
 Wrapper classes of primitive Java types: Byte, Integer, Short, Long,
Boolean, Character, Float, Double
 Byte and character array types: byte[], Byte[], char[], Character[]
 Large numeric types: java.math.BigInteger, java.math.BigDecimal
 Strings: java.lang.String
 Java temporal types: java.util.Date, java.util.Calendar
 JDBC temporal types: java.sql.Date, java.sql.Time, java.sql.Timestamp
 Enumerated types: Any system or user-defined enumerated type
 Serializable objects: Any system or user-defined serializable type
 Опциональная аннотация @Basic может использоваться для
объявления поля persisted
@Entity
public class Employee {
...
@Basic
private String name;
8
Указание физического мэпинга простого типа
 В дополнение к логической аннотации @Basic
существует:
 физическая @Column(name=“Name”);
9
Большие объекты (LOB)
 Для доступа к LOB приложение должно сделать
специальный вызов через JDBC
 @Lob аннотация для того, чтобы указать провайдеру, что
работаем с LOB
 Java типы, которые мэпятся на BLOB поля в БД:
 Byte[]
 byte[]
 Serializable объекты
 @Basic и @Column опциональны
10
Пример. Большие объекты (LOB)
11
Мэпинг Java Enums
 В БД хранится информация, позволяющая восстановить
значение перечисления
 Два способа хранения enum:
 EnumType.STRING сохраняет строковое представление
перечисления
 EnumType.ORDINAL сохраняет порядковый номер
перечисления
12
Transient поля
 Для указания, что атрибут не persisted служит:
 Аннотация @Transient
 Ключевое слово transient
 Поле не будет persisted, если на нем нет
persisted аннотации (@Basic) или если оно не
является атрибутом с правильным типом данных
13
Мэпинг первичного ключа
 Каждая сущность должна иметь мэпинг первичного
ключа в БД
 Атрибут одного из следующих типов может быть
первичным ключом:
 Primitive Java types: byte, int, short, long, char
 Wrapper classes of primitive Java types: Byte, Integer, Short, Long,
Character
 Arrays of primitive or wrapper types: Byte, Integer, Short, Long,
Character
 Strings: java.lang.String
 Large numeric types: java.math.BigInteger
 Temporal types: java.util.Date, java.sql.Date
 @Column может использоваться точно так же как и
при мэпинге прочих полей
14
Генерация первичных ключей
 Существует 4 способа генерации ключей:
 AUTO
 TABLE
 SEQUENCE
 IDENTITY
 Приложение не может закладываться на
использование сгенерированного ключа до
момента сохранения сущности
 Для разных сущностей могут быть использованы
разные стратегии генерации ключа
15
Генерация первичных ключей AUTO
 Фактический способ генерации провайдер
выбирает сам
 Таблица или последовательность все-таки нужна
 Лучше использовать для development стадии
 Способ генерации по умолчанию
16
Генерация первичных ключей TABLE
 Наиболее переносимый подход
 Полный пример:
17
Генерация первичных ключей SEQUENCE
 Не переносимый способ генерации. БД должна
поддерживать объект последовательность (Oracle)
18
Генерация первичных ключей IDENTITY
 Не переносимый способ генерации. БД должна
поддерживать авто генерацию ключа (My SQL)
 После автогенерации ключа провайдеру может
потребоваться SELECT, чтобы выбрать это значение
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
19
Отношения. Определения
 В каждом отношении участвуют две сущности. Каждая из
них выполняет роль (role)
 Одна и та же сущность может играть разные роли в
разных отношениях
 Сущность может ссылаться на сущность, играющую
противоположную роль в отношении. Эта ссылка
называется направленность (directionality)
 Выделяют однонаправленное и бинаправленное
отношение
20
Отношения. Определения
 Удобно думать о каждом двунаправленном
отношении как о паре однонаправленных
 Каждое такое отношение имеет сущность,
выполняющую ссылающуюся роль. Source сущность
 Так же имеет сущность, на которую ссылаются.
Target сущность
21
Отношения. Определения
 Каждая роль имеет количество элеметнов отношения
(cardinality), определяющее может существовать только
один экземпляр сущности или много экземпляров
Unidirectional many-to-one relationship
Bidirectional many-to-many relationship
22
Мэпинг отношений. Обзор
 Каждый мэпинг называется исходя из
cardinality source и target ролей
 Всего может быть 4 комбинации (4
ассоциации) cardinality “one” и “many”:




Many-to-one
One-to-one
One-to-many
Many-to-many
23
Подгруппы ассоциаций
 Ассоциация, где target роль имеет
cardinality one называется single-valued
ассоциацией. К ним относятся:
 Many-to-one
 One-to-one
 Ассоциация, где target роль имеет
cardinality many называется collectionvalued ассоциацией. К ним относятся:
 One-to-Many
 Many-to-Many
24
Many-to-one мэпинг (1 из 3)
На диаграмме:
Employee это source сущность cardinality many.
Department это target сущность cardinality one.
 many-to-one мэпинг определяется аннотированием
атрибута source сущности, ссылающегося на target
сущность
25
Many-to-one мэппинг (2 из 3)
 Foreign key в JPA называется join column
 Обозначается физической аннотацией @JoinColumn
 Роль, которая имеет join column называется owning side
 Роль, которая не имеет join column называется inverse
side
26
Many-to-one мэппинг (3 из 3)
 many-to-one мэпинг всегда определяется на owning роли
 @JoinColumn(name=“DEPT_ID”) является опциональной.
Служит для явного указания вторичного ключа DEPT_ID
 По умолчанию ключ будет targetEntityAttribute_
targetEntityID (DEPATRMENT_ID)
 По соглашению вначале идет логические аннотации,
потом физические
27
One-to-one мэпинг (1 из 2)
 Можно определить точно так же как и many-to-one
 Со стороны БД единственность target сущности
обеспечивается уникальным индексом на foreign ключ
28
Двунаправленный оne-to-one мэпинг (2 из 2)
 При one-to-one мэпинге неважно кто является owing
стороной, а кто inverse. @JoinColumn может быть
определена на любой роли
 Inverse роль может однозначно определить owning роль.
Это достигается аннотацией
@OneToOne(mappedBy=“owningRoleAttribute”)
29
Collection-valued ассоциации
 Ассоциация, где target роль имеет
cardinality many называется collectionvalued ассоциацией. К ним относятся:
 One-to-Many
 Many-to-Many
30
One-to-Many мэпинг (1 из 2)
 Когда source сущность имеет произвольное количество target
сущностей, нет способа определить ключи target сущности в
source сущности
 Поэтому пользуемся foreign ключами target сущности для
ссылки назад к source сущности
 Таким образом, мэпинг many-to-one обратного направления
должен быть определен
 Таким образом, one-to-many мэпинг всегда двунаправленный
31
One-to-Many мэпинг (2 из 2)
 На inverse роли определяем элемент mappedBy. Его значением
является имя атрибута target роли
 Элемент targetEntity указывает класс target роли. Эта роль
является owning стороной (содержит @JoinColumn) отношения
 Вывод:
 many-to-one роль является owning, поэтому join column
определяется на этой стороне
 one-to-many роль является inverse, поэтому mappedBy
элемент должен использоваться на этой стороне
32
Many-to-Many мэпинг
 Каждая роль отношения имеет collection-valued
ассоциацию, которая содержит target сущности
 Определяется указанием аннотации
@ManyToMany одновременно на source и target
сущностях
 Join колонка отсутствует и на source и на target
 Следовательно нельзя формально выделить
owning сущность
 Любая сущность может быть принята за owning.
В этом случае противоположная будет inverse и
должна содержать элемент mappedBy на
owning сущность
33
Пример. Many-to-Many мэпинг
34
Join таблица
 Чтобы ассоциировать сущности в many-to-many
отношении всегда необходима join таблица
 EMP_PROJ содержит только первичные ключи
соединяемых сущностей. Они образуют compound ключ
join таблицы
 Для определения owing сущности, а так же конфигурации
join таблицы служит аннотация @JoinTable
 @JoinTable опциональна. В случае отсутствия аннотации,
провайдер сделает предположения о наименовании join
таблица и foreign ключей соединяемых сущностей
35
Пример
36
Однонаправленные collection-valued мэпинги
 Когда сущность имеет аннотацию @OneToMany, но не
указан элемент mappedBy, провайдер предполагает
однонаправленное отношение с target сущностью
 В этом случае всегда предполагается использование join
таблицы
37
Пример. Однонаправленный OneToMany мэпинг
38
Использование различных коллекций
 При работе с collection-valued ассоциациями могут
использоваться следующие интерфейсы:
 Collection
 Set
 List
 Map
 Должен указываться интерфейс (не конкретный класс),
так как провайдер может подменить имплементацию
коллекции
39
Использование Collection, Set и List
 Collection наиболее общий интерфейс, когда
неважно, какая имплементация реально
используется провайдером
 Set не позволит работать с дублирующимися
сущностями
 List обеспечит некоторый порядок, который
задается с помощью аннотации @OrderBy
40
Использование List (продолжение)
 Значением аннотации является набор атрибутов, по
которым проводится сортировка
 @OrderBy("status DESC, name ASC")
 Для каждого атрибута может указываться порядок
сортировки (ASC или DESC). ASC по умолчанию
 Если в аннотации @OrderBy ни один атрибут не
указывается, то сущности сортируются по первичному
ключу
 Если @OrderBy не указан, сущности не сортируются
 Порядок не сохраняется при вставке списка в БД
41
Пример. Использование List
42
Использование Map
 Удобно хранить коллекцию значений в карте (Map), в
качестве ключа используя какой-либо атрибут target
сущности
 Этот ключевой атрибут должен:
 Быть persistent атрибутом
 Корректно переопределять hashCode() и equals()
 Быть уникальным. По крайней мере в данной выборке
 Для указания ключевого атрибута используется
@MapKey(name=“attribute”)
 Если атрибут не указан, мэпинг будет осуществляться по
ключевому атрибуту
43
Пример. Использование Map
44
Lazy загрузка (Lazy Fetching)
 Значение атрибута FetchType указывает провайдеру на
необходимость немедленной подгрузки данных (EAGER) или
отложенной (LAZY)
 Lazy fetching является только подсказкой провайдеру
 Почти всегда не целесообразно указывать lazy загрузку
простым типам.
 Для простых типов по умолчанию используется EAGER
 Напротив lazy загрузка может иметь большую роль в
производительности системы при загрузке отношений
45
Lazy загрузка отношений
 Для single-valued отношений по умолчанию используется
EAGER загрузка
 Для collection-valued отношений по умолчанию
используется LAZY загрузка
 В двунаправленных отношениях одна сторона может
использовать EAGER загрузку, другая - LAZY
46
Обзор

Аннотации. Виды аннотаций

Доступ к состоянию сущности

Мэпинг сущности на таблицу

Мэпинг простых типов

Мэпинг первичного ключа

Генерация первичных ключей

Отношения. Определения

Виды ассоциаций

Many-to-one мэпинг

One-to-one мэпинг

One-to-Many мэпинг

Many-to-Many мэпинг

Join таблица

Однонаправленные collection-valued мэпинги

Использование коллекций

Lazy загрузка
47