Изучаем Java EE 7 - [97]

Шрифт
Интервал

>Query query = em.createNamedQuery("findAll");

Опять-таки если у вас возникнет необходимость ввести запрос для возврата списка объектов Customer, то придется воспользоваться TypedQuery, как показано далее:

>TypedQuery query = em.createNamedQuery("findAll", Customer.class);

Следующий фрагмент кода вызывает именованный запрос findWithParam с передачей параметра: fname и присваиванием setMaxResults значения 3:

>Query query = em.createNamedQuery("findWithParam");

>query.setParameter("fname", "Винсент");

>query.setMaxResults(3);

>List customers = query.getResultList();

Поскольку большинство методов Query API возвращает объект Query, вы можете использовать элегантное сокращение при написании запросов. Вызывайте методы один за другим (setParameter(). setMaxResults() и т. д.):

>Query query = em.createNamedQuery("findWithParam"). setParameter("fname", 

>··················································"Винсент")

>··················································.setMaxResults(3);

Именованные запросы пригодны для организации определений запросов и являются эффективным средством повышения производительности приложений. Это происходит благодаря тому, что именованные запросы для сущностей определяются статически и обычно располагаются в классе-сущности, который соответствует непосредственно результату запроса (здесь запрос findAll возвращает всех клиентов, поэтому он должен быть определен в сущности Customer).

Есть ограничение: областью видимости для имени запроса является та, что имеет место в случае с единицей сохраняемости. При этом имя должно быть уникальным в этой области видимости, то есть может присутствовать только один метод findAll. Запрос findAll, который касается клиентов, и запрос findAll, касающийся адресов, должны именоваться по-разному. Общепринятая практика — снабжение имени запроса префиксом в виде имени сущности. Например, запрос findAll к сущности Customer имел бы имя Customer.findAll.

Другая проблема заключается в том, что имя запроса, являющееся строкой, подвергается манипуляциям, и, если вы допустите опечатку или выполните реорганизацию своего кода, то могут быть сгенерированы исключения, говорящие о том, что запрос не существует. Чтобы ограничить риски, вы можете заменить имя запроса константой. В листинге 6.23 показано, как произвести реорганизацию сущности Customer.


Листинг 6.23. Сущность Customer и определение именованного запроса с использованием константы

>@Entity

>@NamedQuery(name = Customer.FIND_ALL, query="select c from Customer c"),

>public class Customer {

>··public static final String FIND_ALL = "Customer.findAll";

>··// Атрибуты, конструкторы, геттеры, сеттеры

>}

Константа FIND_ALL однозначно идентифицирует запрос findAll путем снабжения его имени префиксом в виде имени сущности. Та же константа затем используется в аннотации @NamedQuery, и вы можете задействовать ее для выполнения запроса, как показано далее:

>TypedQuery query = em.createNamedQuery(Customer.FIND_ALL, 

>······Customer.class);

Criteria API (или объектно-ориентированные запросы)

До сих пор при написании JPQL-операторов (для выполнения динамических или именованных запросов) я использовал строки. Такой подход удобен тем, что позволяет писать краткие запросы к базам данных. Однако он обладает и недостатками, к которым относятся предрасположенность к ошибкам и сложность манипулирования с помощью внешнего фреймворка. Это строка, а в результате вы прибегаете к конкатенации строк, из-за чего можете допустить множество опечаток. Например, вы можете допустить опечатки в ключевых словах JPQL (SLECT вместо SELECT), именах классов (Custmer вместо Customer) или атрибутов (firstname вместо firstName). Вы также можете написать синтаксически неправильный оператор (SELECT c WHERE c.firstName = 'John' FROM Customer). Любая из этих ошибок будет обнаружена во время выполнения, а иногда может быть сложно выяснить, откуда происходит определенный дефект.

С выходом JPA 2.0 появился новый API-интерфейс под названием Criteria API, определенный в пакете javax.persistence.criteria. Он позволяет вам писать любые запросы объектно-ориентированным и синтаксически правильным образом. Большинство ошибок, которые разработчики могут допустить при написании операторов, выявляется во время компиляции, а не во время выполнения. Идея заключается в том, что все ключевые слова JPQL (SELECT, UPDATE, DELETE, WHERE, LIKE, GROUP BY…) определены в этом API-интерфейсе. Другими словами, Criteria API поддерживает все, что может сделать JPQL, но с использованием основанного на объектах синтаксиса. Впервые взглянем на запрос, который извлекает всех клиентов, для которых firstName имеет значение Vincent. На JPQL он выглядел бы следующим образом:

>SELECT c FROM Customer c WHERE c.firstName = 'Винсент'

Этот JPQL-оператор был переписан в листинге 6.24 объектно-ориентированным образом с использованием Criteria API.


Листинг 6.24. Запрос с использованием критериев, обеспечивающий выборку всех клиентов, для которых firstName имеет значение Vincent

>CriteriaBuilder builder = em.getCriteriaBuilder();


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


MFC и OpenGL

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Симуляция частичной специализации

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Обработка событий в С++

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.