1 / 47

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

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

ronan-hood
Download Presentation

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

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

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

  3. Аннотации • Могут быть определены на уровне • Класса • Метода • Поля • Выделяются 2 логические группы • Логические аннотации • Физические аннотации 3

  4. Доступ к состоянию сущности • Аннотация может быть определена на: • Поле • Методе (провайдер будет использовать метод по умолчанию) • Для доступа используется механизм Java Reflection 4

  5. Аннотирование поля • Модификатор доступа: • 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

  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

  7. Мэпинг сущности на таблицу • @Entity определяет сущность. Обязательное поле • Название таблицы по умолчанию – имя класса • @Table(name=“EMP”, schema=“HR”, catalog=“HR.EMP” @Entity @Table(name="EMP", schema="HR") public class Employee { … } 7

  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 @Entity public class Employee { ... @Basic private String name; 8

  9. Указание физического мэпинга простого типа • В дополнение к логической аннотации @Basic существует: • физическая @Column(name=“Name”); 9

  10. Большие объекты (LOB) • Для доступа к LOB приложение должно сделать специальный вызов через JDBC • @Lob аннотация для того, чтобы указать провайдеру, что работаем с LOB • Java типы, которые мэпятся на BLOB поля в БД: • Byte[] • byte[] • Serializable объекты • @Basic и @Column опциональны 10

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

  12. Мэпинг Java Enums • В БД хранится информация, позволяющая восстановить значение перечисления • Два способа хранения enum: • EnumType.STRING сохраняет строковое представление перечисления • EnumType.ORDINAL сохраняет порядковый номер перечисления 12

  13. Transient поля • Для указания, что атрибут не persisted служит: • Аннотация @Transient • Ключевое слово transient • Поле не будет persisted, если на нем нет persisted аннотации (@Basic) или если оно не является атрибутом с правильным типом данных 13

  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

  15. Генерация первичных ключей • Существует 4 способа генерации ключей: • AUTO • TABLE • SEQUENCE • IDENTITY • Приложение не может закладываться на использование сгенерированного ключа до момента сохранения сущности • Для разных сущностей могут быть использованы разные стратегии генерации ключа 15

  16. Генерация первичных ключей AUTO • Фактический способ генерации провайдер выбирает сам • Таблица или последовательность все-таки нужна • Лучше использовать для development стадии • Способ генерации по умолчанию 16

  17. Генерация первичных ключей TABLE • Наиболее переносимый подход • Полный пример: 17

  18. Генерация первичных ключей SEQUENCE • Не переносимый способ генерации. БД должна поддерживать объект последовательность (Oracle) 18

  19. Генерация первичных ключей IDENTITY • Не переносимый способ генерации. БД должна поддерживать авто генерацию ключа (My SQL) • После автогенерации ключа провайдеру может потребоваться SELECT, чтобы выбрать это значение @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int id; 19

  20. Отношения. Определения • В каждом отношении участвуют две сущности. Каждая из них выполняет роль (role) • Одна и та же сущность может играть разные роли в разных отношениях • Сущность может ссылаться на сущность, играющую противоположную роль в отношении. Эта ссылка называется направленность (directionality) • Выделяют однонаправленное и бинаправленное отношение 20

  21. Отношения. Определения • Удобно думать о каждом двунаправленном отношении как о паре однонаправленных • Каждое такое отношение имеет сущность, выполняющую ссылающуюся роль. Sourceсущность • Так же имеет сущность, на которую ссылаются. Targetсущность 21

  22. Отношения. Определения • Каждая роль имеет количество элеметнов отношения (cardinality), определяющее может существовать только один экземпляр сущности или много экземпляров Unidirectional many-to-one relationship Bidirectional many-to-many relationship 22

  23. Мэпинг отношений. Обзор • Каждый мэпинг называется исходя из cardinality source и target ролей • Всего может быть 4 комбинации (4 ассоциации) cardinality “one” и “many”: • Many-to-one • One-to-one • One-to-many • Many-to-many 23

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

  25. Many-to-one мэпинг (1 из 3) На диаграмме: Employeeэто sourceсущность cardinality many. Departmentэто targetсущность cardinality one. • many-to-one мэпинг определяется аннотированиематрибута source сущности, ссылающегося на target сущность 25

  26. Many-to-one мэппинг (2 из 3) • Foreign key в JPA называется join column • Обозначается физической аннотацией @JoinColumn • Роль, которая имеет join column называетсяowning side • Роль, которая не имеет join column называетсяinverse side 26

  27. Many-to-one мэппинг (3 из 3) • many-to-one мэпинг всегда определяется на owning роли • @JoinColumn(name=“DEPT_ID”) является опциональной. Служит для явного указания вторичного ключа DEPT_ID • По умолчанию ключ будет targetEntityAttribute_ targetEntityID (DEPATRMENT_ID) • По соглашению вначале идет логические аннотации, потом физические 27

  28. One-to-one мэпинг (1 из 2) • Можно определить точно так же как и many-to-one • Со стороны БД единственность target сущности обеспечивается уникальным индексом на foreign ключ 28

  29. Двунаправленный оne-to-one мэпинг (2 из 2) • При one-to-one мэпингеневажно кто является owing стороной, а кто inverse. @JoinColumn может быть определена на любой роли • Inverse роль может однозначно определить owning роль. Это достигается аннотацией @OneToOne(mappedBy=“owningRoleAttribute”) 29

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

  31. One-to-Many мэпинг (1 из 2) • Когда source сущность имеет произвольное количество target сущностей, нет способа определить ключи target сущности в source сущности • Поэтому пользуемся foreign ключами target сущности для ссылки назад к source сущности • Таким образом, мэпинг many-to-one обратного направления должен быть определен • Таким образом, one-to-manyмэпинг всегдадвунаправленный 31

  32. One-to-Many мэпинг (2 из 2) • На inverse роли определяем элемент mappedBy. Его значением является имя атрибута target роли • Элемент targetEntityуказывает класс target роли. Эта роль является owning стороной (содержит @JoinColumn)отношения • Вывод: • many-to-one роль является owning, поэтому join column определяется на этой стороне • one-to-many роль является inverse, поэтому mappedBy элемент должен использоваться на этой стороне 32

  33. Many-to-Many мэпинг • Каждая роль отношения имеет collection-valued ассоциацию, которая содержит targetсущности • Определяется указанием аннотации @ManyToManyодновременно на source и target сущностях • Join колонка отсутствует и на source и на target • Следовательно нельзя формально выделить owning сущность • Любая сущность может быть принята за owning. В этом случае противоположная будет inverse и должна содержать элемент mappedByна owning сущность 33

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

  35. Join таблица • Чтобы ассоциировать сущности в many-to-many отношении всегда необходима join таблица • EMP_PROJ содержит только первичные ключи соединяемых сущностей. Они образуют compound ключ join таблицы • Для определения owing сущности, а так же конфигурации join таблицы служит аннотация @JoinTable • @JoinTableопциональна. В случае отсутствия аннотации, провайдер сделает предположения о наименовании join таблица и foreign ключей соединяемых сущностей 35

  36. Пример 36

  37. Однонаправленные collection-valued мэпинги • Когда сущность имеетаннотацию @OneToMany, но не указан элемент mappedBy, провайдер предполагает однонаправленное отношение с target сущностью • В этом случае всегда предполагаетсяиспользование join таблицы 37

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

  39. Использование различных коллекций • При работе с collection-valued ассоциациями могут использоваться следующие интерфейсы: • Collection • Set • List • Map • Должен указываться интерфейс (не конкретный класс), так как провайдер может подменить имплементацию коллекции 39

  40. Использование Collection,Set и List • Collection наиболее общий интерфейс, когда неважно, какая имплементация реально используется провайдером • Set не позволит работать с дублирующимися сущностями • List обеспечит некоторый порядок, который задается с помощью аннотации @OrderBy 40

  41. Использование List (продолжение) • Значением аннотации является набор атрибутов, по которым проводится сортировка • @OrderBy("status DESC, name ASC") • Для каждого атрибута может указываться порядок сортировки (ASC или DESC). ASC по умолчанию • Если в аннотации @OrderBy ни один атрибут не указывается, то сущности сортируются по первичному ключу • Если @OrderBy не указан, сущности не сортируются • Порядок не сохраняется при вставке списка в БД 41

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

  43. Использование Map • Удобно хранить коллекцию значений в карте (Map), в качестве ключа используя какой-либо атрибут target сущности • Этот ключевой атрибут должен: • Быть persistent атрибутом • Корректно переопределять hashCode() и equals() • Быть уникальным. По крайней мере в данной выборке • Для указания ключевого атрибута используется @MapKey(name=“attribute”) • Если атрибут не указан, мэпинг будет осуществляться по ключевому атрибуту 43

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

  45. Lazy загрузка (Lazy Fetching) • Значение атрибута FetchType указывает провайдеру на необходимость немедленной подгрузки данных (EAGER) или отложенной (LAZY) • Lazy fetching является только подсказкой провайдеру • Почти всегда не целесообразно указывать lazy загрузку простым типам. • Для простых типов по умолчанию используется EAGER • Напротив lazy загрузка может иметь большую роль в производительности системы при загрузке отношений 45

  46. Lazy загрузка отношений • Для single-valued отношений по умолчанию используется EAGER загрузка • Для collection-valued отношений по умолчанию используется LAZY загрузка • В двунаправленных отношениях одна сторона может использовать EAGER загрузку, другая - LAZY 46

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

More Related