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

3 чел.

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, що використовуватиметься цим контейнером.


 

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

77326. RiDE.L – programming language 12 KB
  Kosenko IMM UrB RS USU Yekterinburg With time ti is getting hrder to develop softwre for highperformnce computing HPC; the min reson for tht is the complexity grow of hrdwre rchitectures mthemticl models dt structures nd lgorithms complexity which re pplied in lrge computtions. The lnguges with clssicl compiler rchitectures trditionlly used in HPC: C C FORTRN Pscl – re not so good t hndling tht complexity s lter lnguges: Hskell JvScript Oz Ruby. The best in tht Hskell GHC even when breking hrmonious syntx nd semntic...
77327. DATAFLOW BASED DISTRIBUTED COMPUTING METHODS. SYSTEM PROTOTYPE 20.5 KB
  Different methods re pplied to simplify the progrmming nd execution of prllel progrms. On the one hnd universl tools for utomtic progrm prlleliztion both for execution on shred memory nd for multicomputer systems re being developed. The gol of tht design is to simplify prllel progrm development but without significnt loss in the effectiveness of the progrm codes execution. Term tsk nmes the progrm which reds during its execution the dt items with specific nmes from storge nd s the result...
77328. IMPROVING THE DEVELOPMENT OF VISUALIZATION SOFTWARE 30.5 KB
  Visuliztion helps to interpret results of vrious stges of clcultions. However there is problem of developing of visuliztion tools exist. To explin tht let’s see which types of visuliztion tools re: Universl visuliztion systems cpble to disply visul objects of vrious clsses.
77330. Возможности оценки сложности параллельного программирования 71.5 KB
  Утверждение о том, что параллельное программирование сложно, стало общим местом в соответствующей специальной литературе еще с 80-ых годов XX века. Вместе с тем, необходимо разобраться, чем же оно сложно и как в этом плане соотносятся различные парадигмы параллельного программирования. Анализ сложности программирования полезен
77331. Веб-система визуализации, анализа и мониторинга работы программ 39.5 KB
  Визуализация процесса и параметров работы программ представляет известный интерес для разработчиков этих программ. В научном плане эти вопросы изучает область визуализация программного обеспечения которая особенно активно развивается на западе. Система предназначена для визуализации анализа и мониторинга работы программных комплексов включая и параллельные программы.
77332. EXECUTION TRACE VISUALIZATION FOR PARALLEL PROGRAMS 26.5 KB
  There re mny interesting systems bsed on execution trce visuliztion. In the report s the review of existing decisions s new pproches to development of execution trce visuliztion will be considered. However the min problem tht occurs when you develop trce visuliztion system is the huge nd evergrowing volume of dt to be nlyzed.
77334. «Хороший» интерфейс на основе жестов для манипулирования 3D-объектами и метод автоматической калибровки оптических камер 38 KB
  Интерфейс фонарика Поскольку любой манипулятор ограничивает набор возможных взаимодействий от него следует отказаться и осуществлять пользовательский ввод при помощи трёхмерных жестов. Данное устройство обладая шестью степенями свободы позволяет осуществлять ввод трёхмерных жестов являясь при этом простым в установке и использовании. В качестве дешёвого манипулятора для ввода трёхмерных жестов был выбран обыкновенный карманный фонарик.