Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2013_1 / КСТ / Разработка веб-приложений.pdf
Скачиваний:
160
Добавлен:
23.02.2015
Размер:
2.74 Mб
Скачать

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

Соседние файлы в папке КСТ