Объектно-реляционный мэпинг

47
Объектно-реляционный мэпинг 1

description

Объектно-реляционный мэпинг. 1. Обзор. Аннотации. Виды аннотаций Доступ к состоянию сущности Мэпинг сущности на таблицу Мэпинг простых типов Мэпинг первичного ключа Генерация первичных ключей Отношения. Определения Виды ассоциаций Many-to-one мэпинг One-to-one мэпинг - PowerPoint PPT Presentation

Transcript of Объектно-реляционный мэпинг

Page 1: Объектно-реляционный мэпинг

Объектно-реляционный мэпинг

1

Page 2: Объектно-реляционный мэпинг

ОбзорОбзор

Аннотации. Виды аннотаций Доступ к состоянию сущности Мэпинг сущности на таблицу Мэпинг простых типов Мэпинг первичного ключа Генерация первичных ключей Отношения. Определения Виды ассоциаций Many-to-one мэпинг One-to-one мэпинг One-to-Many мэпинг Many-to-Many мэпинг Join таблица Однонаправленные collection-valued мэпинги Использование коллекций Lazy загрузка

2

Page 3: Объектно-реляционный мэпинг

АннотацииАннотации

Могут быть определены на уровне Класса Метода Поля

Выделяются 2 логические группы Логические аннотации Физические аннотации

3

Page 4: Объектно-реляционный мэпинг

Доступ к состоянию сущностиДоступ к состоянию сущности

Аннотация может быть определена на: Поле Методе (провайдер будет использовать

метод по умолчанию) Для доступа используется механизм Java

Reflection

4

Page 5: Объектно-реляционный мэпинг

Аннотирование поляАннотирование поля

Модификатор доступа: protected, package, private. Не public

Getter и Setter игнорируются@Entitypublic class Employee { @Id private int id; //Не! Будет вызван провайдером public int getId() { return id; } public void setId(int id) { this.id = id; }

....5

Page 6: Объектно-реляционный мэпинг

Аннотирование методаАннотирование метода

Аннотируется 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

Page 7: Объектно-реляционный мэпинг

Мэпинг сущности на таблицуМэпинг сущности на таблицу

@Entity определяет сущность. Обязательное поле

Название таблицы по умолчанию – имя класса @Table(name=“EMP”, schema=“HR”,

catalog=“HR.EMP”@Entity

@Table(name="EMP", schema="HR")

public class Employee {

}

7

Page 8: Объектно-реляционный мэпинг

Мэппинг простых типовМэппинг простых типов

Поля следующих типов могут быть 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

@Entitypublic class Employee { ... @Basic private String name;

8

Page 9: Объектно-реляционный мэпинг

Указание физического мэпинга простого типаУказание физического мэпинга простого типа

В дополнение к логической аннотации @Basic существует:

физическая @Column(name=“Name”);

9

Page 10: Объектно-реляционный мэпинг

Большие объекты (Большие объекты (LOB)LOB)

Для доступа к LOB приложение должно сделать специальный вызов через JDBC

@Lob аннотация для того, чтобы указать провайдеру, что работаем с LOB

Java типы, которые мэпятся на BLOB поля в БД: Byte[] byte[] Serializable объекты

@Basic и @Column опциональны

10

Page 11: Объектно-реляционный мэпинг

Пример. Большие объекты (Пример. Большие объекты (LOB)LOB)

11

Page 12: Объектно-реляционный мэпинг

Мэпинг Мэпинг Java EnumsJava Enums

В БД хранится информация, позволяющая восстановить значение перечисления

Два способа хранения enum: EnumType.STRING сохраняет строковое

представление перечисления EnumType.ORDINAL сохраняет порядковый

номер перечисления

12

Page 13: Объектно-реляционный мэпинг

Transient Transient поляполя

Для указания, что атрибут не persisted служит: Аннотация @Transient Ключевое слово transient

Поле не будет persisted, если на нем нет persisted аннотации (@Basic) или если оно не является атрибутом с правильным типом данных

13

Page 14: Объектно-реляционный мэпинг

Мэпинг первичного ключаМэпинг первичного ключа

Каждая сущность должна иметь мэпинг первичного ключа в БД

Атрибут одного из следующих типов может быть первичным ключом: 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

Page 15: Объектно-реляционный мэпинг

Генерация первичных ключейГенерация первичных ключей

Существует 4 способа генерации ключей: AUTO TABLE SEQUENCE IDENTITY

Приложение не может закладываться на использование сгенерированного ключа до момента сохранения сущности

Для разных сущностей могут быть использованы разные стратегии генерации ключа

15

Page 16: Объектно-реляционный мэпинг

Генерация первичных ключей Генерация первичных ключей AUTOAUTO

Фактический способ генерации провайдер выбирает сам

Таблица или последовательность все-таки нужна

Лучше использовать для development стадии

Способ генерации по умолчанию

16

Page 17: Объектно-реляционный мэпинг

Генерация первичных ключей Генерация первичных ключей TABLETABLE

Наиболее переносимый подход Полный пример:

17

Page 18: Объектно-реляционный мэпинг

Генерация первичных ключей Генерация первичных ключей SEQUENCESEQUENCE

Не переносимый способ генерации. БД должна поддерживать объект последовательность (Oracle)

18

Page 19: Объектно-реляционный мэпинг

Генерация первичных ключей Генерация первичных ключей IDENTITYIDENTITY

Не переносимый способ генерации. БД должна поддерживать авто генерацию ключа (My SQL)

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

19

@Id @GeneratedValue(strategy=GenerationType.IDENTITY)private int id;

Page 20: Объектно-реляционный мэпинг

Отношения. ОпределенияОтношения. Определения

В каждом отношении участвуют две сущности. Каждая из них выполняет роль (role)

Одна и та же сущность может играть разные роли в разных отношениях

Сущность может ссылаться на сущность, играющую противоположную роль в отношении. Эта ссылка называется направленность (directionality)

Выделяют однонаправленное и бинаправленное отношение

20

Page 21: Объектно-реляционный мэпинг

Отношения. ОпределенияОтношения. Определения

Удобно думать о каждом двунаправленном отношении как о паре однонаправленных

Каждое такое отношение имеет сущность, выполняющую ссылающуюся роль. Source сущность

Так же имеет сущность, на которую ссылаются. Target сущность

21

Page 22: Объектно-реляционный мэпинг

Отношения. ОпределенияОтношения. Определения

Каждая роль имеет количество элеметнов отношения (cardinality), определяющее может существовать только один экземпляр сущности или много экземпляров

22

Unidirectional many-to-one relationship

Bidirectional many-to-many relationship

Page 23: Объектно-реляционный мэпинг

Мэпинг отношений. ОбзорМэпинг отношений. Обзор

Каждый мэпинг называется исходя из cardinality source и target ролей

Всего может быть 4 комбинации (4 ассоциации) cardinality “one” и “many”: Many-to-one One-to-one One-to-many Many-to-many

23

Page 24: Объектно-реляционный мэпинг

ПодгруппыПодгруппы ассоциацийассоциаций

Ассоциация, где target роль имеет cardinality one называется single-valued ассоциацией. К ним относятся: Many-to-one One-to-one

Ассоциация, где target роль имеет cardinality many называется collection-valued ассоциацией. К ним относятся: One-to-Many Many-to-Many

24

Page 25: Объектно-реляционный мэпинг

Many-to-one Many-to-one мэпинг (1 из мэпинг (1 из 33))

На диаграмме:

Employee это source сущность cardinality many.

Department это target сущность cardinality one. many-to-one мэпинг определяется

аннотированием атрибута source сущности, ссылающегося на target сущность

25

Page 26: Объектно-реляционный мэпинг

Many-to-one Many-to-one мэппинг (2 из мэппинг (2 из 33))

Foreign key в JPA называется join column Обозначается физической аннотацией

@JoinColumn Роль, которая имеет join column называется

owning side Роль, которая не имеет join column называется

inverse side

26

Page 27: Объектно-реляционный мэпинг

Many-to-one Many-to-one мэппинг (мэппинг (33 из из 33))

many-to-one мэпинг всегда определяется на owning роли

@JoinColumn(name=“DEPT_ID”) является опциональной. Служит для явного указания вторичного ключа DEPT_ID

По умолчанию ключ будет targetEntityAttribute_ targetEntityID (DEPATRMENT_ID)

По соглашению вначале идет логические аннотации, потом физические

27

Page 28: Объектно-реляционный мэпинг

One-to-one One-to-one мэпинг (мэпинг (11 из 2) из 2)

Можно определить точно так же как и many-to-one

Со стороны БД единственность target сущности обеспечивается уникальным индексом на foreign ключ

28

Page 29: Объектно-реляционный мэпинг

Двунаправленный оДвунаправленный оne-to-one ne-to-one мэпинг (мэпинг (22 из 2) из 2)

При one-to-one мэпинге неважно кто является owing стороной, а кто inverse. @JoinColumn может быть определена на любой роли

Inverse роль может однозначно определить owning роль. Это достигается аннотацией @OneToOne(mappedBy=“owningRoleAttribute”)

29

Page 30: Объектно-реляционный мэпинг

Collection-valuedCollection-valued ассоциацииассоциации

Ассоциация, где target роль имеет cardinality many называется collection-valued ассоциацией. К ним относятся:

One-to-Many Many-to-Many

30

Page 31: Объектно-реляционный мэпинг

One-to-Many One-to-Many мэпинг (1 из 2)мэпинг (1 из 2)

Когда source сущность имеет произвольное количество target сущностей, нет способа определить ключи target сущности в source сущности

Поэтому пользуемся foreign ключами target сущности для ссылки назад к source сущности

Таким образом, мэпинг many-to-one обратного направления должен быть определен

Таким образом, one-to-many мэпинг всегда двунаправленный

31

Page 32: Объектно-реляционный мэпинг

One-to-Many One-to-Many мэпинг (2 из 2)мэпинг (2 из 2)

На inverse роли определяем элемент mappedBy. Его значением является имя атрибута target роли

Элемент targetEntity указывает класс target роли. Эта роль является owning стороной (содержит @JoinColumn) отношения

Вывод: many-to-one роль является owning, поэтому join column

определяется на этой стороне one-to-many роль является inverse, поэтому mappedBy

элемент должен использоваться на этой стороне32

Page 33: Объектно-реляционный мэпинг

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

Каждая роль отношения имеет collection-valued ассоциацию, которая содержит target сущности

Определяется указанием аннотации @ManyToMany одновременно на source и target сущностях

Join колонка отсутствует и на source и на target

Следовательно нельзя формально выделить owning сущность

Любая сущность может быть принята за owning. В этом случае противоположная будет inverse и должна содержать элемент mappedBy на owning сущность

33

Page 34: Объектно-реляционный мэпинг

Пример. Пример. Many-to-Many Many-to-Many мэпингмэпинг

34

Page 35: Объектно-реляционный мэпинг

Join Join таблицатаблица

Чтобы ассоциировать сущности в many-to-many отношении всегда необходима join таблица

EMP_PROJ содержит только первичные ключи соединяемых сущностей. Они образуют compound ключ join таблицы

Для определения owing сущности, а так же конфигурации join таблицы служит аннотация @JoinTable

@JoinTable опциональна. В случае отсутствия аннотации, провайдер сделает предположения о наименовании join таблица и foreign ключей соединяемых сущностей

35

Page 36: Объектно-реляционный мэпинг

ПримерПример

36

Page 37: Объектно-реляционный мэпинг

Однонаправленные Однонаправленные collection-valued collection-valued мэпингимэпинги

Когда сущность имеет аннотацию @OneToMany, но не указан элемент mappedBy, провайдер предполагает однонаправленное отношение с target сущностью

В этом случае всегда предполагается использование join таблицы

37

Page 38: Объектно-реляционный мэпинг

Пример. Однонаправленный Пример. Однонаправленный OneToMany OneToMany мэпингмэпинг

38

Page 39: Объектно-реляционный мэпинг

Использование различных коллекцийИспользование различных коллекций

При работе с collection-valued ассоциациями могут использоваться следующие интерфейсы: Collection Set List Map

Должен указываться интерфейс (не конкретный класс), так как провайдер может подменить имплементацию коллекции

39

Page 40: Объектно-реляционный мэпинг

Использование Использование Collection,Collection, Set Set и и ListList

Collection наиболее общий интерфейс, когда неважно, какая имплементация реально используется провайдером

Set не позволит работать с дублирующимися сущностями

List обеспечит некоторый порядок, который задается с помощью аннотации @OrderBy

40

Page 41: Объектно-реляционный мэпинг

Использование Использование ListList (продолжение) (продолжение)

Значением аннотации является набор атрибутов, по которым проводится сортировка @OrderBy("status DESC, name ASC")

Для каждого атрибута может указываться порядок сортировки (ASC или DESC). ASC по умолчанию

Если в аннотации @OrderBy ни один атрибут не указывается, то сущности сортируются по первичному ключу

Если @OrderBy не указан, сущности не сортируются

Порядок не сохраняется при вставке списка в БД

41

Page 42: Объектно-реляционный мэпинг

Пример. Пример. Использование Использование ListList

42

Page 43: Объектно-реляционный мэпинг

Использование Использование MapMap

Удобно хранить коллекцию значений в карте (Map), в качестве ключа используя какой-либо атрибут target сущности

Этот ключевой атрибут должен: Быть persistent атрибутом Корректно переопределять hashCode() и equals() Быть уникальным. По крайней мере в данной

выборке Для указания ключевого атрибута используется

@MapKey(name=“attribute”) Если атрибут не указан, мэпинг будет

осуществляться по ключевому атрибуту

43

Page 44: Объектно-реляционный мэпинг

Пример. Использование Пример. Использование MapMap

44

Page 45: Объектно-реляционный мэпинг

Lazy Lazy загрузка загрузка (Lazy Fetching)(Lazy Fetching)

Значение атрибута FetchType указывает провайдеру на необходимость немедленной подгрузки данных (EAGER) или отложенной (LAZY)

Lazy fetching является только подсказкой провайдеру

Почти всегда не целесообразно указывать lazy загрузку простым типам.

Для простых типов по умолчанию используется EAGER

Напротив lazy загрузка может иметь большую роль в производительности системы при загрузке отношений

45

Page 46: Объектно-реляционный мэпинг

Lazy Lazy загрузка отношенийзагрузка отношений

Для single-valued отношений по умолчанию используется EAGER загрузка

Для collection-valued отношений по умолчанию используется LAZY загрузка

В двунаправленных отношениях одна сторона может использовать EAGER загрузку, другая - LAZY

46

Page 47: Объектно-реляционный мэпинг

ОбзорОбзор

Аннотации. Виды аннотаций Доступ к состоянию сущности Мэпинг сущности на таблицу Мэпинг простых типов Мэпинг первичного ключа Генерация первичных ключей Отношения. Определения Виды ассоциаций Many-to-one мэпинг One-to-one мэпинг One-to-Many мэпинг Many-to-Many мэпинг Join таблица Однонаправленные collection-valued мэпинги Использование коллекций Lazy загрузка

47