- •Обозначения и сокращения
- •введение
- •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. Защита приложения паролем
- •Заключение
- •Библиографический список
13. Язык запросов
Java Persistence Query Language
Язык определяет запросы для сущностей и их хранимых состояний. Язык за-
просов позволяет записывать портируемые запросы, которые работают независимо от используемой основной системы управления базами данных.
Язык запросов использует абстрактные схемы хранения объектов, включая их
связи, для их модели данных, и это определяет операторы и выражения в этой моде-
ли данных. Область видимости запроса распределяет абстрактные схемы связанных
объектов, которые упакованы на том же устройстве хранения. Язык запроса использует SQL-подобный синтаксис, чтобы выбирать объекты или значения на основе аб-
страктной схемы типов сущности и связей между ними.
13.1. Терминология языка запросов
Следующий список определяет некоторые термины, используемые в этой главе.
•Abstract schema: абстрактная схема хранения (хранимые объекты, их состо-
яние и их связи), над которой действуют запросы. Язык запроса переводится в запросы над этой хранимой абстрактной схемой в запросы, выполняющие-
ся в схеме базы данных, на которую объекты отображены.
•Abstract schema type: все выражения имеют тип. Абстрактный тип схемы объекта, производный от класса объекта, и информация метаданных задаются аннотациями языка Java.
•Backus-Naur Form (BNF): нотация, которая описывает синтаксис высокоуров-
невых языков.
•Navigation: путь по связям в выражении языка запроса. Оператор навига-
ции — точка.
•Path expression: выражение, которое указывает на состояние или поле сущности.
•State field: хранимое поле объекта.
•Relationship field: хранимое поле отношения объекта, чей тип является аб-
страктным типом схемы связанного объекта.
13.2.Создание запросов
вJava Persistence Query Language
Методы EntityManager.createQuery и EntityManager.createNamedQuery исполь-
зуются для создания запроса в хранилище данных на языке запросов.
Метод 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();
}
151
Метод createNamedQuery используется для создания статических запросов или
запросов, которые определены в метаданных с использованием аннотации javax.persistence.NamedQuery. Элемент name @NamedQuery определяет имя запроса, который
будет использован методом createNamedQuery. Элемент query @NamedQuery — сам
запрос.
@NamedQuery(
name=”findAllCustomersWithName”,
query=”SELECT c FROM Customer c WHERE c.name LIKE :custName”
)
Пример createNamedQuery, который использует запрос @NamedQuery, опреде-
лённый выше:
@PersistenceContext public EntityManager em;
...
customers = em.createNamedQuery("findAllCustomersWithName")
.setParameter("custName", "Smith")
.getResultList();
13.2.1. Поименованные параметры запросов
Поименованные параметры содержат двоеточие (:) перед своим именем. Поименованные параметры запроса связаны с аргументами метода javax.persistence. Query.setParameter (String name, Object value). В следующем примере аргумент name
для бизнес-метода findWithName связан с параметром :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();
}
Поименованные параметры — регистро-чувствительные и могут быть использованы как динамическими, так и статическими запросами.
13.2.2. Позиционные параметры запроса
Вы можете использовать позиционные параметры в запросах вместо поименованных параметров.
Позиционные параметры обозначены знаком вопроса (?), сопровождающим
числовую позицию параметра в запросе. Метод Query.setParameter(integer position, Object value) используется для установки значения параметра.
В следующем примере бизнес-метод findWithName использует входной позици-
онный параметр:
public List findWithName(String name) { return em.createQuery(
"SELECT c FROM Customer c WHERE c.name LIKE ?1")
.setParameter(1, name)
.getResultList();
}
152
Входные параметры нумеруются, начиная с 1. Входные параметры — регистро-
чувствительные и могут использоваться как динамическими, так и статическими запросами.
13.3.Упрощенный синтаксис языка запросов
13.3.1. Утверждение SELECT
Запрос выбора имеет шесть частей: SELECT, FROM, WHERE, GROUP BY,
HAVING и ORDER BY. SELECT и FROM — обязательные, а WHERE, GROUP BY,
HAVING и ORDER BY — дополнительные. BNF-синтаксис запроса:
QL_statement ::= select_clause from_clause [where_clause][groupby_clause][having_clause][orderby_clause]
Статья SELECT определяет типы объектов или значений, возвращаемых запросом.
FROM определяет область запроса, объявляя один или более идентификаторов переменных,которыемогутбытьуказанывстатьяхSELECT иWHERE.Идентификатор переменной представляет один из следующих элементов:
•абстрактное имя схемы объекта,
•элемент коллекции отношения,
•элемент однозначного отношения,
•элемент коллекции, который является множественной стороной отношения
«один-ко-многим».
WHERE является условным выражением, которое ограничивает объекты или значения, извлеченные запросом.
GROUP BY группирует результаты запроса согласно заданным свойствам.
HAVING используется статьей GROUP BY, чтобы дополнительно ограничивать результаты запроса согласно условному выражению.
ORDER BY сортирует объекты или значения, возвращаемые запросом, в указанном порядке.
13.3.2. Предложения корректировки и удаления
Утверждения корректировки и удаления обеспечивают коллективные операции над наборами объектов. У них следующий синтаксис:
update_statement :: = update_clause [where_clause] delete_statement :: = delete_clause [where_clause]
Коррекция и удаление определяют тип объектов, которые нужно корректиро-
вать или удалять. Может быть использована статья WHERE, чтобы ограничивать об-
ласть сущностей для операции коррекции или удаления.
153
13.4. Примеры запросов
Простой запрос
SELECT p FROM Player p
Результат: все игроки.
Описание: статья FROM объявляет переменную идентификации с именем p,
опуская дополнительное ключевое слово AS. Если ключевое слово AS было включе-
но, то статья должна записываться следующим образом:
FROM Player AS p
Элемент Player является абстрактным именем схемы сущности Player.
Выбор дубликатов сущностей
SELECT DISTINCT p
FROM Player p
WHERE p.position = ?1
Использование именованных параметров
SELECT DISTINCT p FROM Player p
WHERE p.position = :position AND p.name = :name
Результат: игроки, имеющие заданные параметрами позиции и имена.
Описание: имена position и name — хранимые поля сущности Player. WHERE
сравнивает значения этих полей с поименованным параметром запроса, используя метод Query.setNamedParameter. Язык запроса обозначает поименованный входной параметр (двоеточие «:» перед идентификатором). Первый входной параметр —
:position, второй — :name .
13.5.Запросы с навигацией связанных сущностей
На языке запросов выражение может просмотреть связанные сущности. Эти
выражения являются первым различием между языками Java Persistence query language и SQL.
Запросы обрабатывают связанные сущности как соединения таблиц в SQL.
Простой запрос
SELECT DISTINCT p
FROM Player p, IN(p.teams) t
Результат: все игроки, которые принадлежат командам teams.
Описание: статья FROM объявляет две переменных: p и t. Переменная p
представляет сущности Player, а переменная t представляет связанную сущность Team. Декларация для t ссылается на прежде объявленную переменную p. IN — ключевое слово, означающее, что teams является коллекцией связанных сущностей. Выражение p.teams переходит от Player к своей связанной группе Team. Точка в выражении p.teams — оператор навигации.
154
Вы можете также использовать утверждение JOIN, чтобы записать тот же запрос:
SELECT DISTINCT p
FROM Player p JOIN p.teams t
Этот запрос мог также быть записан как:
SELECT DISTINCT p FROM Player p
WHERE p.team IS NOT EMPTY
Навигация в поля отношения Single-Value
Использование утверждения JOIN для навигации в поле однозначного отношения:
SELECT t
FROM Team t JOIN t.league tl
WHERE tl.sport = ’soccer’ OR tl.sport =’football’
В этом примере запрос возвращает все команды ’soccer’ или команды из лиги
’football’.
Просмотр отношений с входным параметром
SELECT DISTINCT p
FROM Player p, IN (p.teams) AS t WHERE t.city = :city
Результат: игроки, чьи команды принадлежат определённому городу.
Описание: Этот запрос подобен предшествующему примеру, но добавляет входной параметр. Ключевое слово AS в статье FROM — дополнительное. В статье WHERE точка, предшествующая хранимому городу — разделитель, а не оператор на-
вигации. Строго говоря, выражения могут делать переходы в поля отношения (свя-
занных сущностей), но не в хранимые поля. Чтобы иметь доступ к хранимому полю, выражение использует точку как разделитель.
Выражения не могут управлять полями отношений, которые являются коллекциями.
В синтаксисе выражения поле-коллекция является терминальным символом.
Поскольку поле teams — коллекция, статья WHERE не может определять p.teams.city
(незаконное выражение).
Просмотр множественных отношений
SELECT DISTINCT p
FROM Player p, IN (p.teams) t WHERE t.league = :league
Результат: игроки, которые принадлежат определённой лиге.
Описание: выражение этого запроса обрабатывает более двух связей. Выражение p.teams управляет отношением Player-Team, выражение t.league управля-
ет отношением Team-League.
В других примерах входные параметры являются сущностями String, но в этом примере параметр является сущностью, чей тип является League. Этот тип соответствует полю отношения лиги в выражении сравнения WHERE.
155