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