- •Обозначения и сокращения
- •введение
- •1. Установка и настройка инструментальных средств
- •1.1. Установка и подготовка к работе операционной системы
- •1.2. Установка программного обеспечения
- •1.3. Создание таблиц в базе данных
- •2. Основы Java EE 6
- •2.1. Распределенные многоуровневые приложения
- •2.2. Контейнеры Java EE
- •2.3. Сервер GlassFish v3
- •2.4. Структура приложения
- •2.5. Конфигурирование приложений
- •2.6. Задание ссылок на ресурсы
- •4. Введение в компоненты Facelets
- •4.1. Веб-страницы
- •4.2. Разработка простого приложения Facelets
- •4.3. Использование шаблонов
- •5. Унифицированный язык записи выражений
- •6.1. Добавление компонент библиотеки HTML на страницу
- •6.2. Использование компонент для таблиц баз данных
- •6.3. Использование тегов библиотеки Core
- •7. Использование конвертеров, слушателей и проверок
- •7.1. Использование стандартных преобразователей
- •7.2. Регистрация слушателей для компонентов
- •8. Внешние объекты (JavaBeans)
- •8.1. Создание класса внешних объектов
- •8.2. Описание свойств бинов
- •8.3. Написание методов внешних бинов
- •8.4. Проверка бинами
- •9.1. Файл конфигурации ресурсов приложения
- •9.2. Упорядочение ресурсов конфигурации приложения
- •9.3. Конфигурирование состояния проекта
- •9.4. Выбор конфигурации бина
- •9.5. Регистрация сообщений об ошибках как пакет ресурса
- •9.7. Конфигурирование правил навигации (Navigation Rules)
- •9.8. Основные требования приложения JavaServer Faces
- •10. Технология Java Servlet
- •11. Введение в Java Persistence API
- •11.1. Требования к классам сущностей
- •11.3. Внедряемые классы в сущностях
- •11.4. Наследование сущностей
- •11.5. Стратегии наследования сущностей с отображением
- •11.6. Управление сущностями
- •11.7. Запросы сущностей
- •12. Примеры хранимых сущностей
- •12.1. Приложение order
- •12.2. Пример получения схемы отношений на основе таблиц БД
- •13.1. Терминология языка запросов
- •13.3. Упрощенный синтаксис языка запросов
- •13.4. Примеры запросов
- •13.5. Запросы с навигацией связанных сущностей
- •13.6. Запросы с другими условными выражениями
- •13.7. Изменение и удаление группы сущностей
- •13.8. Полный синтаксис языка запросов
- •14. Язык запросов Criteria API
- •14.3. Корни запроса
- •14.4. Использование объединения в запросе
- •14.5. Навигация путей в запросах
- •14.6. Ограничения на результаты запроса
- •14.7. Управление результатами запросов
- •14.8. Исполнение запросов
- •15. Связывание ресурсов
- •15.1. Ресурсы и служба имен JNDI
- •15.2. Объекты DataSource и пулы соединений (Connection Pools)
- •15.3. Внедрение ресурсов
- •15.4. Адаптеры ресурсов
- •15.5. Аннотации метаданных
- •16. Безопасность веб-приложений
- •16.1. Краткий обзор
- •16.2. Механизмы обеспечения безопасности
- •16.3. Безопасность сервера предприятия
- •16.4. Использование защищенного соединения SSL
- •18. Пример приложения
- •18.1. Создание проекта веб-приложения
- •18.3.Структура приложения JavaEE 6
- •18.4. Программирование вида для объектов
- •18.5. Дизайн главной страницы
- •18.6. Страница просмотра записей таблицы городов
- •18.7. Страница добавления записей о городах
- •18.8. Страница редактирования записей о городах
- •18.9. Страница удаления записей о городах
- •19. Обработка связей внешних ключей
- •19.1. Разработка класса для вида сущности
- •19.2. Доработка вида для городов
- •19.3. Разработка обзорной страницы
- •19.5. Страница для редактирования записей с внешними ключами
- •20. Дополнительные функции
- •20.1. Сортировка записей таблицы
- •20.2. Контроль за удалением связанных записей
- •20.3. Контроль ввода наименований
- •20.4. Запросы к БД на языке Java Persistence Query Language
- •20.5. Управление страницами при просмотре таблицы
- •20.6. Создание и просмотр отчетов
- •20.7. Использование шаблонов и стилей
- •20.8. Защита приложения паролем
- •Заключение
- •Библиографический список
14. Язык запросов Criteria API
Описание языка запросов Criteria API приведено в части 25 учебника [1].
Подобно языку JPQL, язык Criteria API основывается на абстрактной схеме хранимых сущностей, их отношений и вложенных объектах. Это позволяет разработчикам нахо-
дить, модифицировать и удалять сущности, вызывая операторы Java Persistence API.
Эти языки внутренне связаны и выполняют подобные операции.
Простой пример запроса Criteria Query возвращает экземпляры сущности Pet в
наборе данных:
EntityManager em = ...;
CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Pet> cq = cb.createQuery(Pet.class); Root<Pet> pet = cq.from(Pet.class); cq.select(pet);
TypeQuery<Pet> q = em.createQuery(cq); List<Pet> allPets = q.getResultList();
Эквивалентный запрос JPQL:
SELECT p FROM Pet p
Пример демонстрирует основные шаги в создании запроса Criteria:
•использование экземпляра EntityManager для создания объекта
CriteriaBuilder;
•создание объекта запроса с использованием интерфейса CriteriaQuery. Атрибуты этого запроса будут модифицироваться деталями запроса;
•установка корня запроса вызовом метода объекта CriteriaQuery;
•задание типа результата запроса после вызова метода select объекта
CriteriaQuery;
•подготовка запроса для исполнения путём создания экземпляра объекта класса TypedQuery<T> заданного типа результата;
• исполнение запроса путем вызова метода getResultList объекта TypedQuery<T>. Так как запрос возвращает коллекцию сущностей, результат
имеет тип List.
14.1.Моделирование сущностей
сиспользованием Metamodel API
Metamodel API используется для создания метамодели управления сущностями
в заданном модуле хранилища. Для каждого класса сущности создается класс мета-
модели с подчеркиванием на конце имени и с атрибутами, соответствующими полям или свойствам класса сущности.
В следующем примере класс com.example.Pet имеет четыре хранимых поля: id, name, color и owners:
package com.example;
...
@Entity
public class Pet { @Id
173
protected Long id; protected String name; protected String color; @ManyToOne
protected Set<Person> owners;
...
}
Соответствующий класс метамодели:
package com.example;
...
@Static Metamodel(Pet.class) public class Pet_ {
public static volatile SingularAttribute<Pet, Long> id; public static volatile SingularAttribute<Pet, String> name; public static volatile SingularAttribute<Pet, String> color; public static volatile SetAttribute<Pet, Person> owners;
}
Классы метамодели, соответствующие сущностным классам, имеют тип javax. persistence.metamodel.EntityType<T> и обычно генерируются процессом аннотации или получаются вызовом метода getModel объекта корня запроса либо экземпляром класса Metamodel и затем передаются типу сущности методом entity.
Следующий пример получает динамически класс метамодели использованием метода Root<T>.getModel.
EntityManager em = ...;
CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cq = cb.createQuery(Pet.class); Root<Pet> pet = cq.from(Pet.class); EntityType<Pet> Pet_ = pet.getModel();
Приведённый ниже пример получает динамически класс метамодели использо-
ванием метода Metamodel.getMetamodel. Затем вызывается метод entity метамодели.
EntityManager em = ...; Metamodel m = em.getMetamodel();
EntityType<Pet> Pet_ = m.entity(Pet.class);
14.2.Основы типизации запросов
вCriteria API и Metamodel API
Базовый набор запросов содержит опции select, from, where, как и в запросах
JPQL.
Интерфейс javax.persistence.criteria.CriteriaBuilder используется для создания:
•запросов — Criteria queries;
•выбора — selections;
•выражений — expressions;
•предикатов — predicates;
•сортировки — ordering.
174
Для получения экземпляра интерфейса CriteriaBuilder вызовите метод getCriteriaBuilder для экземпляра EntityManager или EntityManagerFactory. Например:
EntityManager em = ...;
CriteriaBuilder cb = em.getCriteriaBuilder();
Запросы создаются интерфейсом javax.persistence.criteria.CriteriaQuery. Объект
CriteriaQuery определяет навигацию через одну или более сущностей. Он создается
методом CrtieriaBuilder.createQuery. Например:
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);
Тип результата определяется параметром метода. Например, для типа String:
CriteriaQuery<String> cq = cb.createQuery(String.class);
14.3. Корни запроса
Для запросов CriteriaQuery корневая сущность запроса, от которой начинается
навигация, называется query root — корнем запроса. Создается корень вызовом ме-
тода from экземпляра CriteriaQuery. Аргумент для метода from — класс сущности или
экземпляр EntityType<T> для сущности, например, для класса:
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class); Root<Pet> pet = cq.from(Pet.class);
Пример для экземпляра EntityType<T>:
EntityManager em = ...; Metamodel m = em.getMetamodel();
EntityType<Pet> Pet_ = m.entity(Pet.class); Root<Pet> pet = cq.from(Pet_);
Запрос может иметь несколько корней, например:
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class); Root<Pet> pet1 = cq.from(Pet.class);
Root<Pet> pet2 = cq.from(Pet.class);
14.4.Использование объединения в запросе
Для запросов с навигацией по классам сущностей нужно определить объеди-
нение сущностей, вызвав один из методов From.join на объекте корня запроса или
другом объединяемом объекте. Метод join аналогичен ключевому слову JOIN в JPQL.
Цель метода заключается в использовании класса метамодели типа EntityType<T> для задания хранимого поля или свойства объединения сущностей. Метод join возвра-
щает объект типа Join<X, Y>, где X есть исходная сущность, а Y — целевая сущность
объединения. Пример запроса с объединением:
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class); Metamodel m = em.getMetamodel();
EntityType<Pet> Pet_ = m.entity(Pet.class); Root<Pet> pet = cq.from(Pet.class);
Join<Pet, Owner> owner = pet.join(Pet_.owners);
175
Объединения могут быть сцеплены совместно для навигации связанных сущностей без создания экземпляра Join<X, Y> для каждого объединения. Например:
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class); Metamodel m = em.getMetamodel();
EntityType<Pet> Pet_ = m.entity(Pet.class); EntityType<Owner> Owner_ = m.entity(Owner.class);
Root<Pet> pet = cq.from(Pet.class); Join<Owner, Address> address = cq.join(Pet_.owners).join(Owner_.addresses);
14.5. Навигация путей в запросах
Объекты Path используются в опциях запросов select и where и могут быть
сущностями, объединениями сущностей или другими объектами Path. Метод Path.get используется для навигации атрибутов сущностей запроса. Аргумент ме-
тода get соответствует атрибуту сущности класса метамодели. Атрибут может быть
как с одним значением (@SingularAttribute в классе метамодели), так и коллекцией
(@CollectionAttribute, @SetAttribute, @ListAttribute или @MapAttribute ).
Пример использования объекта Path в опции select запроса:
CriteriaQuery<String> cq = cb.createQuery(String.class); Metamodel m = em.getMetamodel();
EntityType<Pet> Pet_ = m.entity(Pet.class); Root<Pet> pet = cq.from(Pet.class); cq.select(pet.get(Pet_.name));
Этот запрос возвращает имена всех любимцев в базе данных. Метод get вызывается для корня запроса pet с именем атрибута класса метамодели Pet_ как аргумент.
14.6. Ограничения на результаты запроса
Метод CriteriaQuery.where позволяет задавать ограничения на результат испол-
нения запроса аналогично ключу WHERE в запросе JPQL. Метод where производит оценку экземпляров интерфейса Expression для отбора результатов согласно условному выражению. Выражение создается методами, определёнными в интерфейсе
Expression и CriteriaBuilder.
14.6.1. Методы интерфейса Expression
Объекты Expression используются в опциях запроса select, where или having.
Методы условных выражений следующие:
•isNull — проверка на значение null;
•isNotNull — проверка на значение не null;
•in — проверка на вхождение в список или коллекцию.
Пример использования выражения для поиска всех объектов с атрибутом color, равным null:
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class); Metamodel m = em.getMetamodel();
EntityType<Pet> Pet_ = m.entity(Pet.class);
176
Root<Pet> pet = cq.from(Pet.class); cq.where(pet.get(Pet_.color).isNull());
Пример использования проверки in:
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class); Metamodel m = em.getMetamodel();
EntityType<Pet> Pet_ = m.entity(Pet.class); Root<Pet> pet = cq.from(Pet.class); cq.where(pet.get(Pet_.color).in("brown", "black");
14.6.2. Методы интерфейса CriteriaBuilder
Интерфейс CriteriaBuilder задаёт дополнительные методы для создания выра-
жений, соответствующие операциям с арифметическими, строковыми данными, дан-
ными времени, даты и операциям выбора и функциям.
Операциями интерфейса CriteriaBuilder являются:
•equal — равенство;
•notEqual — неравенство;
•gt — больше;
•ge — больше или равно;
•lt — меньше;
•le — меньше или равно;
•between — принадлежность интервалу;
•like — проверка шаблоном.
Примеры использования методов CriteriaBuilder:
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class); Metamodel m = em.getMetamodel();
EntityType<Pet> Pet_ = m.entity(Pet.class); Root<Pet> pet = cq.from(Pet.class);
cq.where(cb.equal(pet.get(Pet_.name)), "Fido");
...
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class); Metamodel m = em.getMetamodel();
EntityType<Pet> Pet_ = m.entity(Pet.class); Root<Pet> pet = cq.from(Pet.class);
Date someDate = new Date(...); cq.where(cb.gt(pet.get(Pet_.birthday)), date);
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class); Metamodel m = em.getMetamodel();
EntityType<Pet> Pet_ = m.entity(Pet.class); Root<Pet> pet = cq.from(Pet.class);
Date firstDate = new Date(...); Date secondDate = new Date(...);
cq.where(cb.between(pet.get(Pet_.birthday)), firstDate, secondDate);
177