18122

Java Persistence API

Лекция

Информатика, кибернетика и программирование

PAGE 1 Тема 7: Java Persistence API Java Persistence API забезпечує object/relational mapping для роботи з реляційними даними в Javaпрограмах. Java Persistence складається з трьох частин: Java Persistence API Мови запитів Query language Метаданих для object/relational mapping Entities Entity – це легковісний ...

Украинкский

2013-07-06

77.5 KB

2 чел.

PAGE  1


Тема 7: Java Persistence API

Java Persistence API забезпечує object/relational mapping для роботи з реляційними даними в Java-програмах. Java Persistence складається з трьох частин:

• Java Persistence API

Мови запитів (Query language)

Метаданих для object/relational mapping

Entities

Entityце легковісний клас, об’єкти якого використовується для збереження даних в БД. Зазвичай, entity представляє якусь таблицю реляційної БД, а екземпляр entity відповідає одному рядку таблиці. Інформація для збереження в БД представляється або через persistent-поля, або через persistent-властивості. Ці поля чи властивості використовують анотації об’єктно-реляційного відображення (object/relational mapping annotations) для зв’язування entities та їх зв’язків з реляційними даними в базі даних

Вимоги до Entity-класів

Entity-клас повинен відповідати наступним вимогам:

Клас повинен бути анотований анотацією javax.persistence.Entity.

Клас повинен мати public або protected конструктор без параметрів. Інші конструктори також можуть бути в класі.

Клас не може бути оголошений як final. Методи та поля не можуть бути final.

Якщо екземпляр entity передається за значенням як відокремлений (detached) об’єкт, наприклад, через віддалений бізнес-інтерфейс (remote business interface) session-біна, то клас повинен реалізовувати інтерфейс Serializable.

Entities можуть спадкуватись як від entity, так і не від entity класів; не entity класи можуть спадкуватись від entity класів.

Поля, значення яких зберігатимуться в БД (persistent instance variables) повинні бути оголошені як private, protected чи friendly і можуть бути доступними напряму методами entity-класу. Клієнти повинні мати доступ до стану entity (entitys state) через спеціальні методи доступу або бізнес-методи.

Persistent-поля та властивості в Entity-класах

Persistent-стан entity може бути доступний через поля класу або через властивості як в Java-бінах. Поля і властивості повинні бути відповідних Java-типів:

• Базових типів Java

• java.lang.String

• обгорточних класів базових типів Java

java.math.BigInteger

java.math.BigDecimal

java.util.Date

java.util.Calendar

java.sql.Date

java.sql.Time

java.sql.TimeStamp

• визначених користувачем серіалізованих (serializable) типів

byte[]

Byte[]

char[]

Character[]

• enumerated-типи

• інші entity і колекції entities

• embeddable-класи

Первинні ключі в Entities

Кожна entity має унікальний ідентифікатор об’єкту. Унікальний ідентифікатор (чи первинний ключ) дає можливість виділяти окремі екземпляри серед багатьох. Кожна entity повинна мати первинний ключ. Entity може мати простий або складний первинний ключ. Для позначення простого використовується анотація javax.persistence.Id, яка вказується перед полем чи методом get властивості. Складний первинний ключ може відповідати одній persistent властивості чи полю або набору таких полів чи властивостей. Для складних первинних ключів повинен бути визначений окремий клас первинного ключа. Складні первинні ключі позначаються анотацією  javax.persistence.EmbeddedId або javax.persistence.IdClass. Типи полів чи властивостей первинного ключа (простого чи складного), повинні бути з переліку:

• Базові типи Java

• Обгорточні класи базових типів Java

java.lang.String

java.util.Date

java.sql.Date

Дійсні типи ніколи не можуть включатись в первинний ключ.

Види відношень між Entities

Є чотири типи відношень: один-до-одного, один-до-багатьох, багато-до-одного, і багато-до-багатьох.

Один-до-одного: Кожен екземпляр entity має зв’язок з одним екземпляром іншої entity. Наприклад, в базі даних складу entity StorageBin (пакувальна коробка) і Widget (виріб) мають відношення один-до-одного, якщо в коробці може знаходитись тільки один виріб. Для опису даного відношення використовується анотація javax.persistence.OneToOne перед відповідним persistent полем чи властивістю.

Один-до-багатьох: Екземпляр entity зв’язаний з багатьма екземплярами інших entities. Рахунок-фактура, наприклад, може мати багато позицій. У відповідній програмі, entity Order буде мати відношення один-до-багатьох з  entity LineItem. В даному випадку перед відповідним полем чи властивістю класу Order потрібно поставити анотацію javax.persistence.OneToMany.

Багато-до-одного: Багато екземплярів entity можуть бути зв’язані з одним екземпляром іншого entity. Цей зв’язок є протилежним до один-до-багатьох. В попередньому прикладі, з боку LineItem відношення з Order є багато-до-одного. Таке відношення позначається анотацією javax.persistence.ManyToOne.

Багато-до-багатьох: Багато екземплярів entity можуть бути зв’язаними з багатьма екземплярами іншої entity. Наприклад, в університеті один предмет можуть вивчати багато груп і, з іншого боку, одна група вивчає багато предметів. Для позначення відношення багато-до-багатьох використовується анотація javax.persistence.ManyToMany.

Відношення можуть бути одно направленими або двонаправленими. Двонаправлений зв’язок має головну (owning) та зворотню (inverse) сторони, одно направлений лише головну. Головна сторона визначає, як Persistence runtime робитиме зміни по зв’язкам в базі даних.

Керування Entities

Entities керуються спеціальним entity manager. Entity manager – це об’єкт класу javax.persistence.EntityManager. Кожен екземпляр EntityManager пов’язаний з якимось persistence context. Persistence context – це набір керованих екземплярів entity, що зберігаються в певному сховищі даних. Інтерфейс EntityManager визначає методи, які використовуються для взаємодії з persistence context. EntityManager API створює і видаляє екземпляри entity, знаходить entities за їх первинними ключами і дає можливість виконувати запити, що повертають набори entities.

=======================================

Dependency injection

В Java EE platform, спеціальний механізм dependency injection може бути використана для всіх ресурсів, які потребує компонент, задаючи неявно створення чи пошук компонента в коді програми. Dependency injection може бути використано в EJB-контейнері, web-контейнері або в програмному клієнті. Dependency injection дозволяє Java EE-контейнеру автоматично вставляти посилання на інші потрібні компоненти чи ресурси, використовуючи анотації (annotations, annotation types).

=========================================

Container-Managed Entity Managers

Використовуючи container-managed entity manager,  persistence context  певного екземпляра EntityManager автоматично поширюється контейнером на всі компоненти програми, які використовують екземпляр EntityManager в одній транзакції Java Transaction Architecture (JTA). JTA транзакції зазвичай пов’язані з діями різних компонентів програми. Щоб завершити JTA транзакцію, ці компоненти зазвичай потребують доступу до єдиного persistence context. При цьому EntityManager підключається (is injected) до компонентів програми через анотацію javax.persistence.PersistenceContext. Persistence context автоматично поширюється всередині поточної JTA транзакції і через посилання на EntityManager’и, що відповідають даному persistence модулю, забезпечують доступ до persistence context всередині цієї транзакції. Автоматично поширюючи persistence context, компоненти програми не потребують передачі посилань на екземпляри EntityManager один одному для того, щоб здійснювати зміни всередині однієї транзакції. Java EE контейнер керує життєвим циклом для container-managed entity managers. Щоб отримати посилання на екземпляр EntityManager, потрібно вставити (inject) entity manager в компонент програми:

@PersistenceContext

EntityManager em;

Application-Managed Entity Managers

З іншого боку, при використанні application-managed entity managers, persistence context не поширюється на компоненти програми і життєвий цикл для екземплярів EntityManager керується програмою. Application-managed entity managers використовуються, коли програмі потрібно здійснювати доступ до persistence context, який не поширюється з JTA транзакцією по різних екземплярах EntityManager в рамках persistence модуля. В цьому випадку, кожен EntityManager створює новий, ізольований persistence context. EntityManager і пов’язаний з ним persistence context створюються і знищуються явно програмою. Екземпляри EntityManager створюються в цьому випадку за допомогою методу createEntityManager класу javax.persistence.EntityManagerFactory. Для отримання екземпляру EntityManager, спочатку потрібно створити екземпляр EntityManagerFactory, вставивши його в програму за допомогою анотації javax.persistence.PersistenceUnit:

@PersistenceUnit

EntityManagerFactory emf;

Потім можна записувати:

EntityManager em = emf.createEntityManager();

Знаходження Entities використовуючи EntityManager

Метод EntityManager.find використовується для пошуку entities в сховищі даних з використанням первинного ключа.

@PersistenceContext

EntityManager em;

public void enterOrder(int custID, Order newOrder) {

Customer cust = em.find(Customer.class, custID);

cust.getOrders().add(newOrder);

newOrder.setCustomer(cust);

}

Керування життєвим циклом об’єкту Entity

Керування об’єктами entity відбувається за допомогою викликів операцій над entity з використанням об’єкту EntityManager (фактично, викликів методів EntityManager, параметрами для яких якимось чином вказані об’єкти entity). Об’єкти entity можуть перебувати в одному з чотирьох станів: новий (new), керований (managed), відокремлений (detached) і видалений (removed). Новий об’єкт entity не має унікального persistent-ідентифікатора (первинного ключа) і не зв’язані з persistence context. Керовані об’єкти entity мають persistent-ідентифікатор і зв’язані з persistence context. Відокремлені об’єкти entity  мають persistent-ідентифікатор і в даний момент не зв’язані з persistence context. Видалені entity мають persistent-ідентифікатор, зв’язані з persistent context і поставлені в чергу на вилучення зі сховища даних.

Збереження в базі екземплярів Entity

Нові екземпляри entity стають managed (або persistent) за допомогою виклику методу persist. Це означає, що дані entity зберігаються в базі, коли транзакція, зв’язана з даною операцією persist завершується. Якщо entity вже є managed, то операція persist ігнорується. Якщо persist виконується по відношенню до removed entity, то entity  стає managed. Якщо entity є detached,  то виконання persist викличе IllegalArgumentException або commit транзакції завершиться помилкою.

@PersistenceContext

EntityManager em;

...

public LineItem createLineItem(Order order, Product product, int quantity) {

LineItem li = new LineItem(order, product, quantity);

order.getLineItems().add(li);

em.persist(li);

return li;

}

Операція persist operation поширюється на всі entities, пов’язані з тією, що зберігається, якщо вони мають елемент cascade встановлений в ALL чи PERSIST анотацією зв’язку.

@OneToMany(cascade=ALL, mappedBy="order")

public Collection<LineItem> getLineItems() {

return lineItems;

}

Вилучення екземплярів Entity

Managed екземпляри entity вилучаються через виклик методу remove або через каскадну операцію remove operation, викликану зі зв’язаного entity, що має встановлені елементи cascade=REMOVE або cascade=ALL в анотації відношення. Якщо метод remove викликається до нового entity, то операція remove ігнорується, хоча  remove буде каскадуватись до зв’язаних entities, які мають елемент cascade встановлений в REMOVE або ALL в анотації зв’язку. Якщо  remove викликається до detached entity, буде згенеровано IllegalArgumentException або операція commit транзакції не виконається. Якщо операція remove викликається для вже вилученого об’єкта, вона буде проігнорована. Запис, що відповідає entity буде вилучений з бази коли транзакція завершиться чи буде виконана операція flush.

public void removeOrder(Integer orderId) {

try {

Order order = em.find(Order.class, orderId);

em.remove(order);

}...

Синхронізація даних об’єктів з базою

Стан persistent entities синхронізується з базою, коли завершується по commit транзакція, з якою зв’язаний entity. Для примусової синхронізації managed entity потрібно викликати метод flush. Якщо entity вилучений, виклик flush вилучить entity з бази.

Створення запитів до БД

Методи EntityManager.createQuery and EntityManager.createNamedQuery використовуються для посилання запитів в базу даних з використанням мови Java Persistence query language. Метод createQuery використовується для створення динамічних запитів, тобто запитів, які визначаються безпосередньо всередині бізнес-логіки програми.

public List findWithName(String name) {

return em.createQuery(

"SELECT c FROM Customer c WHERE c.name LIKE :custName")

.setParameter("custName", name)

.setMaxResults(10)

.getResultList();

}

Метод createNamedQuery використовується для створення статичних запитів, тобто запитів, які визначаються в метаданих з використанням анотації javax.persistence.NamedQuery. Елемент name анотації @NamedQuery визначає назву запиту, яка потім використовуватиметься в методі createNamedQuery. Елемент query анотації @NamedQuery – це безпосередньо тест запиту.

@NamedQuery(

name="findAllCustomersWithName",

query="SELECT c FROM Customer c WHERE c.name LIKE :custName"

)

...

@PersistenceContext

public EntityManager em;

...

customers = em.createNamedQuery("findAllCustomersWithName")

.setParameter("custName", "Smith")

.getResultList();

Іменовані параметри в запитах

Іменовані параметри – це параметри в запитах, які починаються з двокрапки.  Іменовані параметри можна замінити фактичним значенням за допомогою метода javax.persistence.Query.setParameter(String name, Object value). В наступному прикладі фактичний параметр name заміняє іменований параметр :custName в запиті за допомогою виклику Query.setParameter.

public List findWithName(String name) {

return em.createQuery(

"SELECT c FROM Customer c WHERE c.name LIKE :custName")

.setParameter("custName", name)

.getResultList();

}

Іменовані параметри чутливі до регістру і можуть використовуватись я к в динамічних, так і в статичних запитах.

Позиційні параметри в запитах

Замість іменованих параметрів можна використовувати позиційні параметри. Позиційні параметри починають зі знака запитання, за яким іде номер параметра в запиті. Метод Query.setParameter(int position, Object value) використовується для задання значення параметру. Приклад:

public List findWithName(String name) {

return em.createQuery(

“SELECT c FROM Customer c WHERE c.name LIKE ?1”)

.setParameter(1, name)

.getResultList();

}

Параметри нумеруються починаючи з 1, є чутливими до регістру і можуть використовуватись як вв динамічних, так і в статичних запитах.

Persistence Units

Persistence unit визначає набір entity класів, які керуються екземплярами EntityManager instances в програмі. Цей набір entity класів представляє дані, що вміщуються в одній БД. Persistence units визначаються в конфігураційному файлі persistence.xml. JAR file чи папка, де папка META-INF вміщує persistence.xml, називається коренем для persistence unit. Зона дії persistence unit визначається його коренем. Кожен persistence unit повинен мати ім’я, унікальним в його зоні дії. Persistence units можуть бути частиною WAR або EJB JAR файлу або можуть бути частиною JAR файлу, який потім може бути включений в WAR або EAR файл. Якщо помістити persistence unit в EJB JAR файл, то persistence.xml потрібно помістити в його папку META-INF. Якщо ж помістити persistence unit в WAR файл, то persistence.xml потрібно помістити в папку WEB-INF/classes/META-INF цього WAR файла. Якщо ж  persistence unit поміщається в JAR файл для подальшого пакування в WAR або EAR файл, то JAR файл потрібно помістити:

в WEB-INF/lib папку WAR файла;

на верхній рівень EAR файла;

в бібліотечну папку EAR файла.

Файл persistence.xml

В persistence.xml визначається один або більше persistence units. Приклад persistence.xml:

<persistence>

   <persistence-unit name="OrderManagement">

<description>This unit manages orders and customers.

It does not rely on any vendor-specific features and can

therefore be deployed to any persistence provider.

</description>

<jta-data-source>jdbc/MyOrderDB</jta-data-source>

<jar-file>MyOrderApp.jar</jar-file>

<class>com.widgets.Order</class>

<class>com.widgets.Customer</class>

   </persistence-unit>

</persistence>

Цей файл визначає persistence unit з назвою OrderManagement, який використовує JTA data source jdbc/MyOrderDB. Елементи jar-file і class визначають керовані persistence класи: entity класи, embeddable класи оабо mapped суперкласи. Елемент jar-file визначає JAR файли, які є видимим для persistence unit, що вміщує керовані persistence класи, а елемент class явно вказує керовані persistence класи. Елементи jta-data-source (для JTA data sources) або non-jta-data-source (для non-JTA data sources) визначають глобальне  JNDI ім’я для data source, що використовуватиметься цим контейнером.


 

А также другие работы, которые могут Вас заинтересовать

62102. Природні зони Північної Америки 342.89 KB
  Тип уроку: засвоєння нових знань Обладнання: учнівські презентації; атласи школярів; авторська презентація ppt Природні зони Північної Америки; листи опорноінформаційних схем школярів. Природні зони Як незвично вони розташовані.
62103. Нумерація чисел 11-20 95.52 KB
  Про що йде в задачі про завод який виготовляв плеєри і телефони Скільки завод виготовив плеєрів 9 Скільки завод виготовив телефонів 7 Про що ми дізнаємося якщо до 9 7 скільки разом виготовили плеєрів і телефонів...
62105. Теорема Виета 31.88 KB
  В соответствии с этим можно выделить следующие структурные элементы данного урока: 1 проверка домашнего задания; 2 подведение учащихся к теореме Виета; 3 формулирование теоремы Виета; 4 доказательство теоремы Виета...