blob: 3e54d7339945827f5ac1810e6ed024106f01b1eb [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta name="author" content="troy.giunipero@sun.com">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="description" content="This tutorial unit demonstrates how to use the IDE to create JPA entity classes from a database, and EJB session beans from entity classes.">
<meta name="keywords" content="NetBeans, IDE, integrated development environment,
Java, Java EE, open source, web technology, e-commerce">
<link rel="stylesheet" type="text/css" href="../../../../netbeans.css">
<link rel="stylesheet" type="text/css" href="../../../../print.css" media="print">
<link rel="stylesheet" type="text/css" href="../../../../lytebox.css" media="screen">
<script type="text/javascript" src="../../../../images_www/js/lytebox-compressed.js"></script>
<title>Учебный курс по электронной коммерции NetBeans. Добавление классов сущностей и сеансных компонентов</title>
</head>
<body>
<!-- Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. -->
<h1>Учебный курс по электронной коммерции NetBeans. Добавление классов сущностей и сеансных компонентов</h1>
<div style="margin-left:-3px">
<div class="feedback-box margin-around float-left" style="margin-right:15px">
<h4>Содержание учебного курса</h4>
<ol>
<li><a href="intro.html">Введение</a></li>
<li><a href="design.html">Проектирование приложения</a></li>
<li><a href="setup-dev-environ.html">Настройка среды разработки</a></li>
<li><a href="data-model.html">Проектирование модели данных</a></li>
<li><a href="page-views-controller.html">Подготовка представлений страниц и сервлета контроллера</a></li>
<li><a href="connect-db.html">Подключение приложения к базе данных</a></li>
<li><strong>Добавление классов сущностей и сеансных компонентов</strong>
<ul style="margin: 5px 0 0 -2em">
<li><a href="#whatEJB">Общие сведения о технологиях EJB и JPA</a></li>
<li><a href="#whatSession">Общие сведения о сеансных компонентах</a></li>
<li><a href="#specification">Спецификации и реализации</a></li>
<li><a href="#addEntity">Добавление классов сущностей</a></li>
<li><a href="#addSession">Добавление сеансных компонентов</a></li>
<li><a href="#access">Доступ к данным при помощи EJB</a></li>
<li><a href="#seeAlso">Дополнительные сведения</a></li>
</ul></li>
<li><a href="manage-sessions.html">Управление сеансами</a></li>
<li><a href="transaction.html">Интеграция транзакционной бизнес-логики</a></li>
<li><a href="language.html">Добавление поддержки языков</a></li>
<li><a href="security.html">Обеспечение безопасности приложений</a></li>
<li><a href="test-profile.html">Тестирование и профилирование</a></li>
<li><a href="conclusion.html">Заключение</a></li>
</ol>
</div>
</div>
<p><img alt="Содержимое на этой странице применимо к IDE NetBeans, версии 6.8 и 6.9" class="stamp" src="../../../../images_www/articles/68/netbeans-stamp-68-69.png" title="Содержимое на этой странице применимо к IDE NetBeans, версии 6.8 и 6.9"></p>
<p>В этом учебном курсе рассмотрены технологии <a href="http://java.sun.com/products/ejb/" target="_blank">Enterprise JavaBeans</a> (EJB) и <a href="http://java.sun.com/javaee/technologies/persistence.jsp" target="_blank">Java Persistence</a> (JPA). Используются необходимые для разработки в Java EE мастеры среды IDE. Это:</p>
<ul style="margin-left: 320px">
<li><strong>Мастер создания классов сущностей из базы данных</strong>Для каждой выбранной таблицы базы данных создается класс сущности, сохраняющий состояние при помощи JPA, с аннотациями именованных запросов, полями, соответствующими столбцам и отношениями, соответствующими внешним ключам.</li>
<li><strong>Мастер сеансных компонентов для классов сущностей</strong>Создает фасад сеанса EJB для каждого класса сущностей с основными методами доступа.</li>
</ul>
<p>Эти два мастера предоставляют эффективный способ быстрого создания модели для приложения. При рассмотрении <a href="design.html#mvcDiagram">диаграммы MVC</a> для создаваемого приложения можно увидеть место расположения сеансных компонентов EJB и классов сущностей JPA в его структуре.</p>
<div class="indent" style="text-align: center">
<img alt="Диаграмма MVC приложения AffableBean" src="../../../../images_www/articles/73/javaee/ecommerce/design/mvc-diagram.png" style="width:596px; margin-top:10px; margin-bottom:10px" title="Диаграмма MVC приложения AffableBean">
</div>
<p>Создаваемые в этом разделе классы сущностей создают представление базы данных <code>affablebean</code> в форме Java. Каждый класс сущностей представляет таблицу базы данных, а экземпляры классов сущностей соответствуют записям, <em>сохраняемым</em> в базе данных. Бизнес-логика приложения инкапсулируется сеансными компонентами, которые могут использоваться как классы <em>фасада</em>, предоставляющие доступ CRUD (создание, чтение, обновление, удаление) к записям (см. ниже), или могут содержать код, реализующий характерные для приложения действия. Пример такого использования приведен в разделе <a href="transaction.html">Раздел 9: интеграция транзакционной бизнес-логики</a>.</p>
<p>Можно просмотреть интерактивную демонстрацию приложения, которое создается в этом учебном курсе: <a href="http://dot.netbeans.org:8080/AffableBean/" target="_blank">Демонстрация приложения электронной коммерции NetBeans</a></p>
<br style="clear:left;">
<br>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Программное обеспечение или материал</th>
<th class="tblheader" scope="col">Требуемая версия</th>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/downloads/index.html" target="_blank">IDE NetBeans</a></td>
<td class="tbltd1">Набор Java, версия 6.8 или 6.9</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" target="_blank">Комплект для разработчика на языке Java (JDK)</a></td>
<td class="tbltd1">версия 6</td>
</tr>
<tr>
<td class="tbltd1"><a href="#glassFish">Сервер GlassFish</a></td>
<td class="tbltd1">v3 или Open Source Edition 3.0.1</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://dev.mysql.com/downloads/mysql/" target="_blank">Сервер базы данных MySQL</a></td>
<td class="tbltd1">Версия 5.1</td>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot3.zip">Проект AffableBean</a></td>
<td class="tbltd1">снимок 3</td>
</tr>
</tbody>
</table>
<p><strong class="notes">Примечания:</strong></p>
<ul>
<li>The IDE NetBeans requires the Java Development Kit (JDK) to run properly. Если указанные материалы не установлены, JDK следует загрузить и установить в первую очередь.</li>
<li>The IDE NetBeans Java Bundle includes Java Web and EE technologies, which are required for the application you build in this tutorial.</li>
<li id="glassFish">The IDE NetBeans Java Bundle also includes the GlassFish server, which you require for this tutorial. Можно <a href="https://glassfish.dev.java.net/public/downloadsindex.html" target="_blank">загрузить сервер GlassFish отдельно</a>, но версия, предоставляемая с NetBeans, имеет преимущество, так как автоматически зарегистрирована в среде IDE.</li>
<li>Этот учебный курс можно выполнять без выполнения предыдущих. Для этого обратитесь к <a href="setup.html">инструкциям по настройке</a>, в которых описана подготовка базы данных и настройка подключений между IDE, GlassFish, и MySQL.</li>
<li><a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot4.zip">Snapshot 4</a> of the <code>AffableBean</code> project is available for download and corresponds to state the project after completing this unit using IDE NetBeans 6.9.</li>
</ul>
<br>
<h2 id="whatEJB">Общие сведения о технологиях EJB и JPA</h2>
<p>До сих пор проект, который создавался в процессе этого учебного курса, можно было запустить на веб-сервере с контейнером сервлетов, таком как Apache Tomcat. Пока использовались только технологии JSTL и сервлетов, а подключение к базе осуществлялось напрямую через JDBC. Теоретически можно продолжать разработку с применением только этих технологий и вручную писать код для всех аспектов приложения, включая многопоточное исполнение, транзакции и безопасность. Однако компоненты EJB и классы сущностей JPA позволяют сосредоточиться на бизнес-логике приложения, используя проверенные и протестированные решения. В следующих разделах рассматриваются данные технологии и их роль в разработке для Java EE.</p>
<ul>
<li><a href="#ejb">JavaBeans Enterprise</a></li>
<li><a href="#jpa">Сохранение состояния Java</a></li>
</ul>
<div class="indent">
<h3 id="ejb">JavaBeans Enterprise</h3>
<p>На официальной <a href="http://java.sun.com/products/ejb/" target="_blank">странице продукта EJB</a> технология EnterPrise JavaBeans описана как &quot;компонентная архитектура клиент-сервер&quot;, которая &quot;позволяет быстро и легко разрабатывать распределенные транзакционные безопасные и переносимые приложения.&quot; При применении EJB все службы, предоставляемые этой технологией, остаются прозрачными для разработчика, избавляя его от утомительного и часто приводящего к ошибкам добавления кода заготовок. Для новичка в разработке для Java EE потребность в EJB для веб-приложения Java неочевидна. В книге Дебу Панды, Реза Рахмана и Дерека Лейна (Debu Panda, Reza Rahman и Derek Lane) <a href="http://www.manning.com/panda/" target="_blank">EJB 3 в действии (EJB 3 In Action)</a> роль EJB четко сформулирована:</p>
<blockquote style="margin-top: 0">
<em>Многие считают, что технология EJB не требуется для разработки сравнительно простых веб-приложений небольшого размера, но это далеко от действительности. Никто не начинает постройку дома с нуля. Постройка начинается с покупки материалов или найма подрядчика. Точно так же неэффективно разрабатывать приложение уровня предприятия с нуля. Большинство приложений на стороне сервера имеют много общего: бизнес-логику, управление состоянием приложения, сохранение и извлечение информации из реляционной базы данных, управление транзакциями, обеспечение безопасности, выполнение асинхронной обработки, интеграцию систем и так далее. <br><br> Контейнер EJB предоставляет эти функциональные возможности в виде встроенных, поэтому компоненты EJB могут использовать их в приложении. Это освобождает разработчика от необходимости изобретать велосипед. Например, при написании модуля обработки кредитных карт в веб-приложении необходимо создать большой объем сложного и приводящего к ошибкам кода для управления транзакциями и контроля безопасности доступа. Можно избежать этого, используя декларативные транзакции и службы безопасности контейнера EJB. Эти службы доступны компонентам EJB при развертывании в контейнере EJB, как и многие другие. Это позволяет создавать высококачественные многофункциональные приложения гораздо быстрее, чем можно подумать.</em><sup><a href="#footnote1" id="1" style="text-decoration:none">[1]</a></sup>
</blockquote>
<p>EJB можно рассматривать как компоненты или как классы Java, включенные в проект, а также как <em>платформу</em>, предоставляющую множество служб, связанных с уровнем предприятия. Некоторое службы, использованные в этом учебном курсе, описаны в книге <a href="http://www.manning.com/panda/" target="_blank">EJB 3 в действии</a> следующим образом:</p>
<ul>
<li><strong>Создание пула:</strong>для каждого компонента EJB платформа EJB создает пул совместно используемых клиентами экземпляров компонента. В любой момент времени каждый экземпляр из пула может использоваться только одним клиентом. После завершения обслуживания клиента экземпляр возвращается в пул для повторного использования вместо уничтожения и восстановления сборщиком мусора.</li>
<li><strong>Многопоточная ориентированность:</strong> EJB делает все компоненты ориентированными на многопоточное исполнение и высокопроизводительными. Это означает, что серверные компоненты можно писать так же, как и однопоточные настольные приложения. Сложность компонента не имеет значения. Многопоточное исполнение обеспечивается технологией EJB.</li>
<li><strong>Транзакции:</strong> EJB поддерживает управление объявленными транзакциями, которое позволяет добавить транзакционное поведение к компонентам путем настройки, а не программирования. В результате можно сделать транзакционным любой метод компонента. При нормальном завершении метода EJB подтверждает транзакцию и сохраняет сделанные методом изменения. В противном случае выполняется откат транзакции. Транзакции EJB, управляемые контейнером, продемонстрированы в разделе<a href="transaction.html">Раздел 9: интеграция транзакционной бизнес-логики</a>.</li>
<li><strong>Безопасность:</strong> EJB поддерживает интеграцию с интерфейсом API службы проверки подлинности и авторизации Java (JAAS), поэтому теперь легче выстроить безопасность и защитить приложения, используя несложные настройки, вместо того, чтобы загромождать программу кодами безопасности. <sup><a href="#footnote2" id="2" style="text-decoration:none">[2]</a></sup>В разделе 11:<a href="security.html#secureEJB">Обеспечение безопасности приложений</a>была продемонстрирована аннотация &lt;a href="http://download.oracle.com/javaee/6/api/javax/annotation/security/RolesAllowed.html" target="_blank"<code>@RolesAllowed</code></a> EJB.</li>
</ul>
<h3 id="jpa">Сохранение состояния Java</h3>
<p>В контексте Java Enterprise <em>сохранение состояния</em> — это автоматическое сохранение данных из объектов Java в реляционной базе данных. <a href="http://java.sun.com/javaee/technologies/persistence.jsp" target="_blank">Интерфейс API сохранения состояния Java</a> (Java Persistence API, JPA) — технология объектно-реляционного сопоставления (ORM), позволяющая приложению прозрачным для разработчика образом управлять данными в объектах Java и реляционной базе данных. Это означает, что можно применить JPA к проекту, добавив и настроив набор классов (<em>сущностей</em>), соответствующих модели данных. После этого приложение сможет получать доступ к этим сущностям как при прямом доступе к базе данных.</p>
<p>Преимущества использования JPA:</p>
<ul>
<li>Для выполнения статических и динамических запросов в JPA используется собственный язык запросов, схожий с SQL. При использовании языка запросов Java Persistence Query Language (JPQL) приложения можно переносить между базами данных различных поставщиков.</li>
<li>Можно избежать написания низкоуровневого кода JDBC/SQL.</li>
<li>JPA предоставляет прозрачные службы для кэширования данных и оптимизации производительности.</li>
</ul>
</div>
<br>
<h2 id="whatSession">Общие сведения о сеансных компонентах</h2>
<p>Сеансные компоненты уровня предприятия вызываются клиентом для выполнения конкретных бизнес-операций. Слово <em>сеансные</em> означает, что экземпляры компонентов доступны в течение &quot;периода обработки&quot;. <a href="http://jcp.org/aboutJava/communityprocess/final/jsr318/index.html" target="_blank">Спецификация EJB 3.1</a> описывает следующие характеристики типичного сеансного объекта:</p>
<ul class="toc">
<li>Выполнение для одного клиента</li>
<li>Способность работать с транзакциями</li>
<li>Обновление данных в основной базе данных</li>
<li>Отсутствие прямого представления общих данных из базы данных несмотря на возможность использования и обновления таких данных</li>
<li>Непродолжительное время существования</li>
<li>Удаление при сбое контейнера EJB Для продолжения вычислений клиент должен повторно установить сеансный объект.</li>
</ul>
<p>EJB предоставляет три вида сеансных компонентов: <em>с поддержкой состояния</em>, <em>без поддержки состояния</em> и <em>одноэкземплярные</em>. Следующие определения взяты из <a href="http://download.oracle.com/docs/cd/E17410_01/javaee/6/tutorial/doc/index.html" target="_blank">учебного курса Java EE 6</a>.</p>
<ul>
<li><strong>С поддержкой состояния:</strong> состояние компонента сохраняется между вызовами методов. &quot;Состояние&quot; &ndash; это значения переменных экземпляра. Поскольку клиент взаимодействует с компонентом, это состояние часто называют <em>диалоговым</em>.</li>
<li><strong>Без поддержки состояния:</strong> такие компоненты используется для операций, происходящих в течение одного вызова метода. При завершении выполнения метода состояние, зависящее от клиента, не сохраняется. Компонент без сохранения состояния не поддерживает диалоговое состояние с клиентом.</li>
<li><strong>Одноэкземплярный:</strong> одноэкземплярный сеансный компонент создается в приложении в единственном числе и существует в течение всего жизненного цикла приложения. Одноэкземплярные сеансные компоненты созданы для ситуаций, в которых один экземпляр компонента уровня предприятия совместно и одновременно используется клиентами.</li>
</ul>
<p class="tips">Дополнительные сведения о сеансных компонентах EJB приведены в документе <a href="http://download.oracle.com/docs/cd/E17410_01/javaee/6/tutorial/doc/gipjg.html" target="_blank">Учебный курс Java EE 6: общие сведения о сеансных компонентах</a>.</p>
<p>Для разработки приложения электронной коммерции в этом учебном курсе используются только сеансные компоненты без сохранения состояния.</p>
<br>
<h2 id="specification">Спецификации и реализации</h2>
<p>Технологии EJB и JPA определены в следующих спецификациях:</p>
<ul>
<li><a href="http://jcp.org/en/jsr/summary?id=317" target="_blank">Сохранение состояния Java</a></li>
<li><a href="http://jcp.org/en/jsr/summary?id=318" target="_blank">JSR 318: Enterprise JavaBeans 3.1</a></li>
</ul>
<p>Указанные спецификации определяют данные технологии. При этом для применения технологии в проекте нужна <em>реализация</em> спецификации. После утверждения спецификации в нее включается ссылочная реализация, которая является свободной реализацией технологии. Если такая концепция вызывает удивление, можно рассмотреть следующую аналогию: музыкальная композиция (т.е. ноты на странице) определяет музыкальное произведение. Когда музыкант заучивает композицию и записывает ее исполнение, происходит <em>интерпретация</em> произведения. Таким образом, музыкальная композиция напоминает техническую спецификацию, а процесс записи музыки перекликается с реализацией спецификации.</p>
<p class="tips">Подробные сведения о технических спецификациях Java и их формальной стандартизации приведены в <a href="intro.html#jcp">описании Java Community Process</a>.</p>
<p>На странице загрузки окончательной редакции спецификаций EJB и JPA находятся ссылки на следующие примеры реализации:</p>
<ul>
<li><strong>JPA:</strong> <a href="http://www.eclipse.org/eclipselink/downloads/ri.php" target="_blank">http://www.eclipse.org/eclipselink/downloads/ri.php</a></li>
<li><strong>EJB:</strong> <a href="http://glassfish.dev.java.net/downloads/ri" target="_blank">http://glassfish.dev.java.net/downloads/ri</a></li>
</ul>
<p>Примеры реализации спецификации JPA называются <em>поставщиками сохранения состояния</em>, а поставщиком сохранения состояния, который был выбран в качестве эталонной реализации для спецификации JPA, версия 2.0, является <a href="http://www.eclipse.org/eclipselink/" target="_blank">EclipseLink</a>.</p>
<p>Ссылка на пример эталонной реализации EJB также приведет на страницу, где упомянуты не только реализации EJB, но и все примеры реализации, предоставленные <a href="https://glassfish.dev.java.net/" target="_blank">проектом GlassFish</a>. Причиной является то, что проект GlassFish предоставляет эталонную реализацию спецификации <a href="http://jcp.org/en/jsr/summary?id=316" target="_blank">JSR 316</a> для платформы Java EE 6. Сервер приложений GlassFish, версия 3 (или версия с открытым исходным кодом), который используется в данном учебном курсе для создания проекта по интернет-коммерции, содержит эталонные реализации всех технологий, разработанных в проекте GlassFish. В связи с этим такой сервер приложений называют <em>контейнером</em> Java EE 6.</p>
<p>Контейнер Java EE содержит три необходимых компонента: веб-контейнер (например, сервлет), контейнер EJB и поставщик сохранения состояния. Сценарий развертывания приложения электронной коммерции показан на диаграмме. Классы сущностей, создаваемые в этой главе, управляются поставщиком сохранения состояния. Создаваемые в этой главе сеансные компоненты управляются контейнером EJB. Представления отображаются страницами JSP, которые управляются веб-контейнером.</p>
<div id="gf-java-ee-container" class="indent">
<img alt="Контейнер Java EE GlassFish в3" class="margin-around" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/java-ee-container.png" title="Будучи контейнером Java EE, GlassFish в.3 содержит веб-контейнеры и контейнеры EJB и EclipseLink, поставщик сохраняемости">
</div>
<br>
<h2 id="addEntity">Добавление классов сущностей</h2>
<p>Вначале используйте мастер создания классов сущностей из базы данных в среде IDE для создания классов сущностей на основе схемы <code>affablebean</code>. При выполнении этого действия мастеру требуется поставщик сохранения состояния.</p>
<ol>
<li>Откройте<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot3.zip">снимок проекта</a> в среде IDE. В IDE нажмите Ctrl-Shift-O (âŚ�-Shift-O в Mac) и перейдите к местоположению на компьютере, где был распакован загруженный файл.</li>
<li>Нажмите сочетание клавиш CTRL+N (⌘-N на компьютере Mac) для открытия мастера создания файлов.</li>
<li>Выберите категорию &quot;Сохранение состояния&quot; и затем &quot;Классы сущностей из базы данных&quot;. Нажмите кнопку &quot;Далее&quot;.</li>
<li>На втором экране мастера &quot;Таблицы базы данных&quot; выберите в списке источников данных <code>jdbc/affablebean</code>. Выпадающий список заполняется зарегистрированными на сервере приложений источниками данных. <br><br> При выборе источника данных <code>jdbc/affablebean</code> среда IDE сканирует базу данных и перечисляет таблицы в панели &quot;Доступные таблицы&quot;. <br> <img alt="Классы сущностей из мастера баз данных" class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/entity-from-database.png" style="width: 688px" title="Выберите доступный источник данных для чтения IDE в таблицах баз данных"></li>
<li>Нажмите кнопку &quot;Добавить&quot;, а затем - кнопку &quot;Далее&quot;.</li>
<li>Step 3 of the Entity Classes from Database wizard differs slightly between IDE NetBeans 6.8 and 6.9. В зависимости от используемой версии IDE выполните следующие шаги.
<ul style="margin: 5px 0 0 -1em">
<li><a href="#68">IDE NetBeans 6.8</a></li>
<li><a href="#69">IDE NetBeans 6.9</a></li>
</ul>
<h4 id="68">IDE NetBeans 6.8</h4>
<img alt="Классы сущностей из мастера баз данных, Step 3: Классы сущностей" class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/entity-classes-68.png" title="NetBeans 6.8 - классы сущностей из мастера баз данных, Step 3: Классы сущностей" width="688px">
<ol style="list-style-type: lower-alpha">
<li>Введите <strong>название сущности</strong> в поле &quot;Пакет&quot;. После завершения работы мастера будет создан новый пакет для классов сущностей.</li>
<li>Нажмите кнопку &quot;Создать блок сохранения состояния&quot;. Будет открыто диалоговое окно &quot;Создание блока сохранения состояния&quot;. <br> <img alt="Диалоговое окно &quot;Создание блока сохранения состояния&quot;." class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/create-pu.png" title="Используйте диалоговое окно 'Создание блока сохранения состояния' для создания файла persistence.xml"> <br> <em>Блок сохранения состояния</em> ссылается на набор классов сущностей приложения. Описанное выше диалоговое окно создает файл <code>persistence.xml</code>, который используется поставщиком сохранения состояния для определения параметров блока сохранения состояния. Обратите внимание, что для проекта по умолчанию выбран сервер EclipseLink (JPA 2.0). Оставьте для стратегии генерирования таблиц значение <code>Нет</code>. Это предотвращает изменения базы данных поставщиком сохранения состояния. Например, если требуется, чтобы поставщик сохранения состояния удалил базу данных, а затем снова создал ее на основе классов сущностей, можно выбрать стратегию <code>Удалить и создать</code>. Теперь каждый раз при развертывании проекта будет выполняться это действие.</li>
<li>Нажмите кнопку &quot;Создать&quot;.</li>
<li>Отобразится третий экран &quot;Классы сущностей&quot;. Обратите внимание, что имена классов сущностей зависят от таблиц базы данных. Например, сущность <code>CustomerOrder</code> связана с таблицей базы данных <code>customer_order</code>. Также обратите внимание, что по умолчанию выбран параметр &quot;Создание аннотаций именованных запросов для сохраняемых полей&quot;. В этом учебном курсе будут использованы различные именованные запросы.</li>
<li>Продолжение смотрите ниже в <a href="#step7">шаге 7</a>.</li>
</ol>
<h4 id="69">IDE NetBeans 6.9</h4>
<img alt="Классы сущностей из мастера баз данных, Step 3: Классы сущностей" class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/entity-classes-69.png" title="NetBeans 6.9 - классы сущностей из мастера баз данных, Step 3: Классы сущностей" width="688px">
<ol style="list-style-type: lower-alpha">
<li>Введите <strong>название сущности</strong> в поле &quot;Пакет&quot;. После завершения работы мастера будет создан новый пакет для классов сущностей.</li>
<li>Обратите внимание:
<ul style="margin: 5px 0 0 -2em">
<li>имена классов сущностей зависят от таблиц базы данных. Например, сущность <code>CustomerOrder</code> связана с таблицей базы данных <code>customer_order</code>.</li>
<li>Параметр &quot;Создать аннотации именованных запросов для сохраняемых полей&quot; выбирается по умолчанию. В этом учебном курсе будут использованы различные именованные запросы.</li>
<li>Флажок &quot;Создать блок сохранения состояния&quot; установлен по умолчанию. <em>Блок сохранения состояния</em> — это набор классов сущностей приложения. Сохранение состояния определяется файлом настройки <code>persistence.xml</code>, который используется поставщиком сохранения состояния. Включение этого параметра означает, что мастер создает также файл <code>persistence.xml</code> и заполняет его параметрами по умолчанию.</li>
</ul>
</li>
</ol></li>
<li id="step7">Нажмите кнопку &quot;Завершить&quot;. Классы сущностей JPA будут созданы на основе таблиц базы данных <code>affablebean</code>. Классы сущностей можно просмотреть в окне &quot;Проекты&quot;, развернув только что созданный пакет <code>entity</code>. Обратите внимание, что новый блок сохранения состояния появляется в узле &quot;Файлы настройки&quot;. <br> <img alt="Окно 'Проекты' - классы сущностей отображаются в проекте" class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/entity-classes.png" title="Узлы для сущностных классов можно будет увидеть в окне Projects (&quot;Проекты&quot;)."> <br><br> Обратите внимание, что был создан дополнительный класс сущностей <code>OrderedProductPK</code>. Таблица <code>ordered_product</code> в модели данных использует составной первичный ключ, состоящий из первичных ключей таблиц <code>customer_order</code> и <code>product</code>. Ознакомьтесь с разделом <a href="data-model.html#manyToMany">Проектирование модели данных — создание связей &quot;многие ко многим&quot;</a>. Поэтому поставщик сохранения состояния создает отдельный класс сущностей для составного ключа и <em>внедряет</em> его в сущность <code>OrderedProduct</code>. Для просмотра класса откройте его в редакторе <code>OrderedProduct</code>. Чтобы показать, что внедряемый класс является составным первичным ключом, в JPA используется аннотация <code>@EmbeddedId</code>.
<pre class="examplecode">
public class OrderedProduct implements Serializable {
private static final long serialVersionUID = 1L;
<strong>@EmbeddedId</strong>
protected OrderedProductPK orderedProductPK;</pre>
<p class="tips">Нажмите сочетание клавиш CTRL+ПРОБЕЛ на аннотации <code>@EmbeddedId</code> для вызова документации по интерфейсу API.</p>
<img alt="Документация API вызвана в @EmbeddedId" class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/embedded-id.png" title="Для вызова документации по API нажмите сочетание клавиш CTRL+ПРОБЕЛ."></li>
<li id="pu">Откройте в редакторе блок сохранения состояния (<code>persistence.xml</code>). Для блоков сохранения состояния в среде IDE, кроме представления XML, доступно представление &quot;Проектирование&quot;. Представление &quot;Проектирование&quot; позволяет удобно вносить изменения в параметры проекта, касающиеся управления поставщиком сохранения состояния. <br> <img alt="Представление проектирования AffableBeanPU единицы сохранения" class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/persistence-unit.png" style="width: 688px" title="Представление проектирования AffableBeanPU единицы сохранения"></li>
<li>Чтобы открыть представление XML, выберите вкладку &quot;XML&quot; в верхней части блока сохранения состояния <code>AffableBeanPU</code>. Добавьте в файл следующее свойство.
<pre class="examplecode">
&lt;persistence-unit name=&quot;AffableBeanPU&quot; transaction-type=&quot;JTA&quot;&gt;
&lt;jta-data-source&gt;jdbc/affablebean&lt;/jta-data-source&gt;
<strong>&lt;properties&gt;
&lt;property name=&quot;eclipselink.logging.level&quot; value=&quot;FINEST&quot;/&gt;
&lt;/properties&gt;</strong>
&lt;/persistence-unit&gt;</pre>
Параметр протоколирования устанавливается в значение <code>FINEST</code> для просмотра всего вывода поставщика сохранения состояния при запуске приложения. Это позволяет увидеть запросы SQL к базе данных, используемые поставщиком сохранения состояния, и облегчает отладку. <br><br>
<p class="tips">См. официальную документацию по EclipseLink, чтобы получить представление о журналировании и список всех значений журнала, в разделе <a href="http://wiki.eclipse.org/EclipseLink/Examples/JPA/Logging" target="_blank">&quot;Как настроить журналирование&quot;</a></p></li>
</ol>
<br>
<h2 id="addSession">Добавление сеансных компонентов</h2>
<p>В этом разделе для создания <em>фасада сеанса</em> каждого созданного класса сущностей будет использован мастер среды IDE &quot;Сеансные компоненты для классов сущностей&quot;. В каждом сеансном компоненте будут содержаться основные методы доступа к соответствующему классу сущностей.</p>
<p><em>Фасад сеанса</em> — это шаблон проектирования, рекомендуемый <a href="http://java.sun.com/blueprints/enterprise/index.html" target="_blank">программе Enterprise BluePrints</a>. Как указано в документе <a href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/SessionFacade.html" target="_blank">Core J2EE Pattern Catalog</a>, этот компонент пытается решить общие проблемы, возникающие в многопоточном приложении, например:</p>
<ul class="toc">
<li>Жесткие связи, приводящие к прямой зависимости между клиентскими и бизнес-объектами.</li>
<li>Излишние вызовы методов между клиентом и сервером, приводящие к проблемам производительности сети.</li>
<li>Недостаточная общность стратегий доступа клиентов, что вызывает недопустимое использование бизнес-объектов.</li>
</ul>
<p>Фасад сеанса маскирует взаимодействие основных бизнес-объектов и создает уровень служб, предоставляющий только необходимые функциональные возможности. Это позволяет скрыть от клиента сложную схему взаимодействия участников. Таким образом, сеансный компонент (т.е. фасад сеанса) управляет взаимодействием бизнес-объектов. Сеансный компонент также управляет жизненным циклом участников, создавая, находя, редактируя и удаляя их в соответствии с рабочим процессом.</p>
<ol>
<li>Нажмите сочетание клавиш CTRL+N (⌘-N на компьютере Mac) для открытия мастера создания файлов.</li>
<li>В категории &quot;Сохранение состояния&quot; выберите &quot;Сеансные компоненты для классов сущностей&quot;. <br> <img alt="Мастер файлов: Категория 'Сохранение состояния', компоненты Bean для типа файлов классов сущностей" class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/session-beans-for-entity-classes.png" style="width: 688px" title="Выберите компоненты Beans сеанса для классов сущностей для создания фасадного сеанса для модели сохраняемости"></li>
<li>Нажмите кнопку &quot;Далее&quot;.</li>
<li>Второй экран &quot;Классы сущностей&quot;. Обратите внимание, что все классы сущностей проекта перечислены слева в разделе &quot;Доступные классы сущностей&quot;. Нажмите кнопку &quot;Добавить все&quot;. Все классы сущностей перемещаются вправо в раздел &quot;Выбранные классы сущностей&quot;.</li>
<li>Нажмите кнопку &quot;Далее&quot;.</li>
<li>Третий экран &quot;Созданные сеансные компоненты&quot;. Введите <strong>session</strong> в качестве имени пакета. <br> <img alt="Компоненты Bean сеанса для мастера классов сущностей - Шаг 3: Созданные компоненты Bean сеанса" class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/generated-session-beans.png" title="Укажите местоположение загруженных исходных файлов в папке в &quot;Source&quot;."> <br>
<p class="notes"><strong>Примечание.</strong> Мастер может использоваться для создания локальных и удаленных интерфейсов к сеансным компонентам. Программирование сеансных компонентов с интерфейсами предпочтительнее (например, скрытие взаимодействия бизнес-объектов за интерфейсом позволяет отделить клиента от бизнес-логики, а при необходимости можно реализовать несколько вариантов интерфейса приложения). В то же время рассмотрение этого процесса выходит за рамки данного учебного курса. Обратите внимание, что версии EJB до 3.1 <em>требуют</em> реализации интерфейса для каждого сеансного компонента.</p></li>
<li>Нажмите кнопку &quot;Завершить&quot;. В среде IDE создаются сеансные компоненты для каждого класса сущностей проекта. В окне &quot;Проекты&quot; разверните новый пакет <code>session</code> для просмотра сеансных компонентов. <br><br>
<table>
<tr class="align-left">
<th style="padding-left:10px">Net Beans, версия 6.8</th>
<th style="padding-left:10px">Net Beans, версия 6.9</th>
</tr>
<tr>
<td>
<img alt="Окно 'Проекты' - компоненты Bean отображаются в проекте" class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/projects-window-session-beans.png" title="Изучите проект CalculatorClientApp в окне &quot;Проекты&quot;. ">
</td>
<td>
<img alt="Окно 'Проекты' - компоненты Bean отображаются в проекте" class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/projects-window-session-beans-69.png" title="Изучите проект CalculatorClientApp в окне &quot;Проекты&quot;. ">
</td>
</tr>
</table>
<p class="notes"><strong>Примечание.</strong> Как показано выше, IDE NetBeans 6.9 обеспечивает незначительные усовершенствования аналогично созданию мастером компонентов сеансов для классов сущностей фасадных классов. А именно, код-заготовка, общий для всех классов, складывается в абстрактный класс, названный <code>AbstractFacade</code>. Работая в версии 6.9, откройте любой из созданных фасадных классов (кроме класса <code>AbstractFacade</code>). Видно, что этот класс расширяет <code>AbstractFacade</code>.</p></li>
<li>Откройте сессионный фасад в редакторе, например в <code>ProductFacade</code>. Все редактируемые сессионные фасады создают <a href="http://java.sun.com/javaee/6/docs/api/javax/persistence/EntityManager.html" target="_blank"><code>EntityManager</code></a>, используя аннотацию <a href="http://download.oracle.com/javaee/6/api/javax/persistence/PersistenceContext.html" target="_blank"><code>@PersistenceContext</code></a>.
<pre class="examplecode">
@PersistenceContext(unitName = "AffableBeanPU")
private EntityManager em;</pre>
Аннотация <code>@PersistenceContext</code> используется для добавления в класс интерфейса <code>EntityManager</code>, управляемого контейнером. Другими словами, контейнер EJB проекта GlassFish используется для открытия и закрытия интерфейсов <code>EntityManager</code>, когда это необходимо. Элемент <code>unitName</code> указывает блок сохранения состояния <code>AffableBeanPU</code>, который был определен в файле <code>persistence.xml</code> приложения. <br><br> <code>EntityManager</code> (диспетчер сущностей) — внутренний компонент интерфейса API сохранения состояния Java, отвечающий за сохранение состояния в базе данных. В книге <a href="http://www.manning.com/panda/" target="_blank">EJB 3 в действии</a> <code>EntityManager</code> описан следующим образом:
<blockquote>
<em>Интерфейс JPA <code>EntityManager</code> управляет сущностями в терминах реального обеспечения служб сохранения состояния. Когда сущности сообщают поставщику JPA о своем сопоставлении с базой данных, они не сохраняют свое состояние самостоятельно. Интерфейс <code>EntityManager</code> считывает метаданные ORM для сущности и производит операции сохранения состояния.</em>
</blockquote></li>
<!-- TEXT CURRENTLY NOT USED:
In the above example, the <code>EntityManager</code>'s <code>createQuery</code>
method is called to perform a query on the database. If you examine the
<code>createQuery</code> API documentation (press Ctrl-Space on the method
in the editor), you see that the method takes a Java Persistence Query Language
(JPQL) query string as an argument, and returns a <code>Query</code> object.
<br>
<img src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/create-query-api.png"
class="margin-around b-all" alt="API documentation for EntityManager's createQuery method"
style="width:688px" title="Press Ctrl-Space to view API documentation">
<br>
<p class="tips">For more information on the JPQL, including terminology, syntax,
and example queries, see the
<a href="http://download.oracle.com/docs/cd/E17410_01/javaee/6/tutorial/doc/bnbtg.html" target="_blank">Java
EE 6 Tutorial, Chapter 21: The Java Persistence Query Language</a>.</p>
The <code>Query</code> object in turn calls <code>setParameter</code> to
bind the <code>categoryId</code> parameter used in the query string with the
the <code>Category</code> object that is passed into the method. Finally,
<code>getResultList()</code> is called to execute a <code>SELECT</code> query
and return the query results as a <code>List</code> of <code>Product</code>s.
-->
</ol>
<p>Теперь приложение содержит модель сохранения состояния базы данных <code>affablebean</code> в форме классов сущностей JPA. Также оно содержит фасад сеанса, состоящий из компонентов уровня приложения, используемых для доступа к классам сущностей. В следующем разделе показан способ доступа к базе данных при помощи сеансных компонентов и классов сущностей.</p>
<br>
<h2 id="access">Доступ к данным при помощи EJB</h2>
<p>В <a href="connect-db.html">предыдущей главе учебного курса</a> показан способ доступа к базе данных путем настройки источника данных в GlassFish, добавления ссылки на ресурс к описателю развертывания приложения и использования тега JSTL <code>&lt;sql&gt;</code> на страницах JSP приложения. Это важный способ, поскольку он позволяет быстро настроить прототипы, включающие в себя данные из базы данных. Тем не менее, такой способ не подходит для средних и крупных приложений или приложений, управляемых командой разработчиков, так как сложен в расширении и поддержке. Более того, при разработке многоуровневого приложения или соблюдении шаблона MVC не следует хранить код доступа к данным в внешнем интерфейсе. Использование компонентов уровня предприятия с моделью сохранения состояния позволяет более полно следовать шаблону MVC благодаря разделению компонентов представления и модели.</p>
<p>Следующая инструкция описывает использование сеансных компонентов и компонентов сущностей в проекте <code>AffableBean</code>. В примере будет удален код доступа к данным JSTL, написанный ранее для страницы-указателя и страницы категории. Вместо них будут использованы методы доступа к данным сеансных компонентов, а данные будут храниться в контекстных переменных, которые доступны из внешнего интерфейса. Для начала отредактируем страницу-указатель, а затем - более сложную страницу категории.</p>
<ul>
<li><a href="#index">страница-указатель</a></li>
<li><a href="#category">страница категории</a></li>
</ul>
<div class="indent">
<h3 id="index">страница-указатель</h3>
<p>На странице-указателе требуются данные о четырех категориях продуктов. При текущих настройках теги JSTL <code>&lt;sql&gt;</code> запрашивают в базе данных сведения при каждом запросе к странице-указателю. Поскольку эта информация редко изменяется, с точки зрения производительности разумнее выполнить запрос только раз после того, как приложение будет запущено, и сохранить данные в атрибуте на уровне приложения. Этого можно добиться, добавив данный код в принадлежащий классу <code>ControllerServlet</code> метод <code>инициализации</code>.</p>
<ol>
<li>В окне &quot;Проекты&quot; дважды щелкните узел &quot;Исходные пакеты&quot; &gt; <code>controller</code> &gt; <code>ControllerServlet</code>, чтобы открыть его в редакторе.</li>
<li>Объявите экземпляр <code>CategoryFacade</code> и примените к нему аннотацию <code>@EJB</code>.
<pre class="examplecode">
public class ControllerServlet extends HttpServlet {
<strong>@EJB
private CategoryFacade categoryFacade;</strong>
...
}</pre>
После добавления аннотации <code>@EJB</code> контейнер EJB создает экземпляр переменной <code>categoryFacade</code> с EJB <code>CategoryFacade</code>.</li>
<li>С помощью подсказок среды IDE добавьте операторы импорта для следующих классов:
<ul style="margin: 5px 0 0 -1em">
<li><code>javax.ejb.EJB</code></li>
<li><code>session.CategoryFacade</code></li>
</ul>
<p class="tips">При нажатии Ctrl-Shift-I (⌘-Shift-I в Mac) требуемые импорты автоматически добавляются к используемому классу.</p></li>
<li>Добавьте в класс следующий метод <code>init</code>. Веб-контейнер инициализирует сервлет, вызывая свой метод <code>init</code>. Это происходит только один раз после загрузки сервлета и до начала обработки запросов.
<pre class="examplecode">
public class ControllerServlet extends HttpServlet {
@EJB
private CategoryFacade categoryFacade;
<strong>public void init() throws ServletException {
// store category list in servlet context
getServletContext().setAttribute(&quot;categories&quot;, categoryFacade.findAll());
}</strong>
...
}</pre>
Здесь метод фасадного класса <code>findAll</code> применяется для запроса из базы данных всех записей категории <code>Category</code>. Затем полученный <code>список</code> объектов <code>Category</code> устанавливается в атрибут, обозначаемый строкой <code>categories</code>. Размещение ссылки в <code>ServletContext</code> означает, что ссылка действует в контексте всего приложения. <br><br>
<p class="tips">Чтобы быстро определить подпись метода <code>findAll</code> подведите мышь к методу, удерживая клавишу Ctrl (⌘ в Mac). (The image below displays the popup that appears using IDE NetBeans 6.8.)</p>
<img alt="Появится всплывающее окно, отображающее сигнатуру метода." class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/method-signature.png" title="Подведите мышь к методу, удерживая клавишу Ctrl для просмотра его подписи."> <br> Щелкните гиперссылку для перехода к методу.</li>
<li>С помощью подсказки среды IDE добавьте аннотацию <code>@Overrides</code> Метод <code>init</code> определяется надклассом <code>HttpServlet</code> и сервлетом <code>GenericServlet</code>. <br> <img alt="Подсказка отображается в редакторе" class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/override.png" title="С помощью подсказки среды IDE добавьте аннотацию @Overrides "> <br> Добавление аннотации не обязательно, но дает следующие преимущества:
<ul style="margin: 5px 0 0 -1em">
<li>Позволяет компилятору проверить, действительно ли переопределяется метод, который предполагается переопределить.</li>
<li>Улучшает удобство восприятия, поскольку становится ясно, какие методы в исходном коде переопределяются.</li>
</ul>
<p class="tips">Дополнительные сведения об аннотациях приведены в курсе <a href="http://download.oracle.com/javase/tutorial/java/javaOO/annotations.html" target="_blank">Учебные курсы по Java: аннотации</a>.</p></li>
<li>После создания в контексте приложения атрибута, содержащего список категорий, измените страницу-указатель таким образом, чтобы использовался этот атрибут. <br><br> Дважды щелкните узел &quot;Веб-страницы&quot; &gt; <code>index.jsp</code> в окне &quot;Проекты&quot;, чтобы открыть файл в редакторе.</li>
<li>Закомментируйте (или удалите) оператор <code>&lt;sql:query&gt;</code> в начале файла. Для закомментирования кода в редакторе выделите код, затем нажмите Ctrl-/ (⌘-/ в Mac).<br> <img alt="Фрагмент с добавленным комментарием отображается в редакторе" class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/commented-out.png" title="Нажмите Ctrl-/ для закомментирования фрагмента кода в редакторе"></li>
<li>Отредактируйте открывающий тег <code>&lt;c:forEach&gt;</code> так, чтобы его атрибут <code>items</code> указывал на новый атрибут контекста приложения <code>categories</code>.
<pre class="examplecode">&lt;c:forEach var=&quot;category&quot; items=&quot;<strong>${categories}</strong>&quot;&gt;</pre></li>
<li>Откройте дескриптор развертывания веб-проекта. Нажмите сочетание клавиш ALT+SHIFT+O (CTRL+SHIFT+O в Mac OS) и в диалоговом окне &quot;Переход к файлу&quot; введите <code>web</code>, затем нажмите кнопку &quot;ОК&quot;. <br> <img alt="Диалоговое окно 'Перейти к файлу'" class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/common/go-to-file.png" title="С помощью диалогового окна &quot;Переход к файлу&quot; быстро откройте файлы в редакторе"></li>
<li>Закомментируйте (или удалите) запись <code>&lt;resource-ref&gt;</code>. Эта запись требовалась для определения тегами <code>&lt;sql&gt;</code> источника данных, зарегистрированного на сервере. Теперь для доступа к базе данных используется JPA, и источник данных <code>jdbc/affablebean</code> уже был указан в блоке сохранения состояния. Подробные сведения представлены выше в разделе <a href="#pu">Представление проектирования поставщика сохранения состояния проекта</a>. <br><br> Выделите всю запись <code>&lt;resource-ref></code>, затем нажмите Ctrl-/ (⌘-/ в Mac).
<pre class="examplecode">
<strong>&lt;!-- </strong>&lt;resource-ref&gt;
&lt;description&gt;Connects to database for AffableBean application&lt;/description&gt;
&lt;res-ref-name&gt;jdbc/affablebean&lt;/res-ref-name&gt;
&lt;res-type&gt;javax.sql.ConnectionPoolDataSource&lt;/res-type&gt;
&lt;res-auth&gt;Container&lt;/res-auth&gt;
&lt;res-sharing-scope&gt;Shareable&lt;/res-sharing-scope&gt;
&lt;/resource-ref&gt; <strong>--&gt;</strong></pre></li>
<li>Выполните проект. Нажмите кнопку 'Запустить проект' ( <img alt="Кнопка 'Выполнить проект'" src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"> ). В браузере откроется страница-указатель проекта, и отобразятся все четыре категории и изображения. <br> <img alt="Убедитесь в том, что к базе данных добавлены новые таблицы." class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/index-page.png" style="width:688px" title="Убедитесь в том, что к базе данных добавлены новые таблицы."></li>
</ol>
<h3 id="category">страница категории</h3>
<p>Для верного отображения <a href="design.html#category">страницы категории</a> требуются три элемента данных:</p>
<ol style="margin: 5px 0 0 -1em" class="toc">
<li><strong>данные о категориях:</strong> для кнопок категорий в левом столбце;</li>
<li><strong>выбранная категория:</strong> выбранная категория выделяется в левом столбце и ее имя отображается над таблицей продуктов;</li>
<li><strong>данные о продуктах в выбранной категории:</strong> для отображения продуктов в таблице.</li>
</ol>
<p>Рассмотрим отдельно каждый элемент данных.</p>
<ul style="margin: 5px 0 0 -1.5em">
<li><a href="#categoryData">данные о категориях</a></li>
<li><a href="#selectedCategoryData">выбранная категория</a></li>
<li><a href="#productData">данные о продуктах в выбранной категории</a></li>
</ul>
<h4 id="categoryData">данные о категориях</h4>
<p>Для получения данных о категориях можно повторно использовать атрибут в контексте приложения <code>categories</code>, созданный для страницы-указателя.</p>
<ol>
<li>Откройте <code>category.jsp</code> в редакторе и закомментируйте (Ctrl-/; ⌘-/ в Mac) операторы JSTL <code>&lt;sql></code>, указанные в верхней части файла. <br> <img alt="<sql> операторы с добавленными комментариями в редакторе" class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/comment-out-sql.png" title="Закомментируйте операторы JSTL <sql> на странице категорий"></li>
<li>Отредактируйте открывающий тег <code>&lt;c:forEach&gt;</code> так, чтобы его атрибут <code>items</code> указывал на атрибут контекста приложения <code>categories</code>. Эта же операция была проведена в файле <code>index.jsp</code>.
<pre class="examplecode">&lt;c:forEach var=&quot;category&quot; items=&quot;<strong>${categories}</strong>&quot;&gt;</pre></li>
<li>Выполните проект для проверки текущего состояния страницы категории. Нажмите кнопку 'Запустить проект' ( <img alt="Кнопка 'Выполнить проект'" src="../../../../images_www/articles/73/javaee/ecommerce/common/run-project-btn.png"> ). После отображения страницы-указателя в браузере щелкните одну из категорий. Кнопки категорий в левом столбце отображаются и работают ожидаемым образом. <br> <img alt="Убедитесь в том, что к базе данных добавлены новые таблицы." class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/category-page-left-column.png" style="width:688px" title="Кнопки категорий в левом столбце отображаются и работают ожидаемым образом."></li>
</ol>
<h4 id="selectedCategoryData">выбранная категория</h4>
<p>Чтобы извлечь выбранную категорию, можно использовать переменную <code>categoryFacade</code>, созданную ранее для поиска <code>Category</code>, чей идентификатор совпадает со строкой запроса.</p>
<ol>
<li>Откройте в редакторе <code>ControllerServlet</code>. Если он уже открыт, нажмите сочетание клавиш CTRL+TAB и выберите его во всплывающем списке.</li>
<li>Начните реализовывать функциональность по принятию выбранной категории Найдите комментарий <code>TODO: Implement category request</code> (Сделать: реализовать запрос категории), удалите его и добавьте следующий код (выделен <strong>полужирным шрифтом</strong>).
<pre class="examplecode">
// if category page is requested
if (userPath.equals(&quot;/category&quot;)) {
<strong>// get categoryId from request
String categoryId = request.getQueryString();
if (categoryId != null) {
}</strong>
// if cart page is requested
} else if (userPath.equals(&quot;/viewCart&quot;)) {</pre>
В этом запросе вызовом функции <code>getQueryString()</code> извлекается идентификатор запрашиваемой категории. <br><br>
<p class="notes"><strong>Примечание.</strong> Логика определения выбранной категории кнопками левого столбца уже реализована в <code>category.jsp</code> с использованием выражения EL, что сравнимо с вызовом <code>getQueryString()</code> в сервлете. Выражение EL: <code>pageContext.request.queryString</code>.</p></li>
<li>Добавьте в оператор <code>if</code> следующую строку кода.
<pre class="examplecode">
// get categoryId from request
String categoryId = request.getQueryString();
if (categoryId != null) {
<strong>// get selected category
selectedCategory = categoryFacade.find(Short.parseShort(categoryId));</strong>
}</pre>
С помощью принадлежащего классу <code>CategoryFacade</code><code>поискового</code> метода возвращается объект <code>Category</code>, который связан с идентификатором запрашиваемой категории. Обратите внимание, что необходимо привести <code>categoryId</code> к типу <code>Short</code>, поскольку такой тип используется в поле <code>id</code> класса сущностей <code>Category</code>.</li>
<li>Щелкните метку ( <img alt="Метка подсказки" src="../../../../images_www/articles/73/javaee/ecommerce/common/editor-badge.png"> ) на левой границе для использования подсказки в редакторе для объявления <code>selectedCategory</code> как локальной переменной в методе <code>doGet</code>. <br> <img alt="Редактор" class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/local-variable.png" title="Использование подсказок редактора для объявления локальных переменных"> <br> Поскольку <code>selectedCategory</code> имеет тип <code>Category</code>, который не был ранее импортирован в класс, среда IDE автоматически добавляет выражение импорта для <code>entity.Category</code> в начало файла.</li>
<li>Чтобы поместить полученный объект <code>Category</code> в контекст запроса, добавьте следующую строку.
<pre class="examplecode">
// get categoryId from request
String categoryId = request.getQueryString();
if (categoryId != null) {
// get selected category
selectedCategory = categoryFacade.find(Short.parseShort(categoryId));
<strong>// place selected category in request scope
request.setAttribute(&quot;selectedCategory&quot;, selectedCategory);</strong>
}</pre></li>
<li>Переключитесь в редакторе к файлу <code>category.jsp</code>. Для этого нажмите сочетание клавиш CTRL+TAB и выберите его во всплывающем списке.</li>
<li>Найдите текст <code>&lt;p id=&quot;categoryTitle&quot;&gt;</code> и внесите следующие изменения.
<pre class="examplecode">
&lt;p id=&quot;categoryTitle&quot;&gt;
&lt;span style=&quot;background-color: #f5eabe; padding: 7px;&quot;&gt;<strong>${selectedCategory.name}</strong>&lt;/span&gt;
&lt;/p&gt;</pre>
Теперь используется атрибут <code>selectedCategory</code>, помещенный в контекст запроса в <code>ControllerServlet</code>. С помощью &quot;<code>.name</code>&quot; в выражении EL вызывается метод <code>getName</code> в данном объекте <code>Category</code>.</li>
<li>Переключитесь обратно на окно браузера и обновите страницу категорий. Теперь на странице отображается имя выбранной категории. <br> <img alt="Убедитесь в том, что к базе данных добавлены новые таблицы." class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/category-page-selected-category.png" style="width:688px" title="Теперь на странице отображается имя выбранной категории.">
</li>
</ol>
<h4 id="productData">данные о продуктах в выбранной категории</h4>
<p>Для того чтобы получить все продукты из выбранной категории, используется принадлежащий сущности <code>Category</code> метод <code>getProductCollection()</code>. Запустите вызов этого метода для <code>selectedCategory</code>, чтобы получить коллекцию всех <code>Product</code>, связанных с <code>selectedCategory</code>. Далее сохраните коллекцию продуктов в контексте запроса как атрибут и, наконец, сошлитесь на контекстный атрибут из представления страницы <code>category.jsp</code>.</p>
<ol>
<li>Добавьте следующий оператор в код <code>ControllerServlet</code>. Это выражение управляет запросом категории.
<pre class="examplecode">
// if category page is requested
if (userPath.equals(&quot;/category&quot;)) {
// get categoryId from request
String categoryId = request.getQueryString();
if (categoryId != null) {
// get selected category
selectedCategory = categoryFacade.find(Short.parseShort(categoryId));
// place selected category in request scope
request.setAttribute(&quot;selectedCategory&quot;, selectedCategory);
<strong>// get all products for selected category
categoryProducts = selectedCategory.getProductCollection();</strong>
}</pre>
Здесь вызов <code>getProductCollection</code> позволяет получить коллекцию всех продуктов <code>Product</code>, связанных с выбранной категорией <code>selectedCategory</code>.</li>
<li>Используйте подсказку редактора для определения <code>categoryProducts</code> в качестве локальной переменной для метода <code>doGet</code>. <br> <img alt="Редактор" class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/local-variable2.png" title="Использование подсказок редактора для объявления локальных переменных"></li>
<li>Поместите коллекцию продуктов <code>Product</code> в контекст запроса, чтобы ее можно было извлечь из внешнего интерфейса приложения.
<pre class="examplecode">
// if category page is requested
if (userPath.equals(&quot;/category&quot;)) {
// get categoryId from request
String categoryId = request.getQueryString();
if (categoryId != null) {
// get selected category
selectedCategory = categoryFacade.find(Short.parseShort(categoryId));
// place selected category in request scope
request.setAttribute(&quot;selectedCategory&quot;, selectedCategory);
// get all products for selected category
categoryProducts = selectedCategory.getProductCollection();
<strong>// place category products in request scope
request.setAttribute(&quot;categoryProducts&quot;, categoryProducts);
}</strong></pre></li>
<li>Откройте в редакторе <code>category.jsp</code> и внесите в таблицу запросов следующее изменение.
<pre class="examplecode">
&lt;table id=&quot;productTable&quot;&gt;
&lt;c:forEach var=&quot;product&quot; items=&quot;<strong>${categoryProducts}</strong>&quot; varStatus=&quot;iter&quot;&gt;</pre>
Тег <code>&lt;c:forEach&gt;</code> теперь ссылается на набор <code>categoryProducts</code>. Цикл <code>c:forEach</code> теперь выполняется для каждого объекта <code>Product</code>, содержащегося в коллекции, и извлекает соответствующие данные.</li>
<li>Для запуска проекта нажмите клавишу F6 (или сочетание клавиш fn+F6 в Mac OS) В браузере перейдите к странице категории и обратите внимание, что для каждой категории отображаются все продукты. <br> <img alt="Убедитесь в том, что к базе данных добавлены новые таблицы." class="margin-around b-all" src="../../../../images_www/articles/73/javaee/ecommerce/entity-session/category-page-product-table.png" style="width:688px" title="Убедитесь в том, что к базе данных добавлены новые таблицы.">
</li>
</ol>
</div>
<p>Этот учебный курс — краткое введение в технологии JPA и EJB. Также здесь описана роль спецификаций Java и использование примеров их реализации в сервере приложений GlassFish. Показано, как создать набор классов сущностей JPA, предоставляющих реализацию базы данных проектов на уровне Java. Затем в соответствии с шаблоном <em>фасад сеанса</em> показано создание набора сеансных компонентов EJB, которые расположены выше уровнем, чем классы сущностей, и предоставляют удобный доступ к ним. Наконец, проект <code>AffableBean</code> изменен для того, чтобы использовать новые сеансные компоненты и сущности для доступа к базе данных. Это требовалось в странице-указателе и странице категорий.</p>
<p>You can download <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot4.zip">snapshot 4</a> of the <code>AffableBean</code> project, which corresponds to state the project after completing this unit using IDE NetBeans 6.9.</p>
<p>В следующей главе будет рассмотрено управление сеансами и запоминание приложением действий пользователя, который перемещается по сайту. Это ключевой момент при реализации механизма &quot;покупательской корзины&quot; в приложениях электронной коммерции.</p>
<div class="feedback-box">
<a href="/about/contact_form.html?to=3&amp;subject=Feedback: NetBeans E-commerce Tutorial - Adding Entity Classes and Session Beans">Мы ждем ваших отзывов</a></div>
<br style="clear:both;">
<br>
<h2 id="seeAlso">Дополнительные сведения</h2>
<div class="indent">
<h3>Материалы по NetBeans</h3>
<ul>
<li><a href="../../../trails/java-ee.html" target="_blank">Учебная карта по Java EE и Java Web</a></li>
<li><a href="../javaee-intro.html" target="_blank">Введение в технологию Java EE </a></li>
<li><a href="../javaee-gettingstarted.html" target="_blank">Начало работы с приложениями для Java EE</a></li>
<li><a href="../secure-ejb.html" target="_blank">Создание безопасных компонентов уровня предприятия в Java EE</a></li>
<li><a href="../javaee-entapp-ejb.html" target="_blank">Создание приложения уровня предприятия с помощью EJB 3.1</a></li>
<li><a href="../jpa-eclipselink-screencast.html" target="_blank">Использование поддержки JPA с EclipseLink</a> [экранная демонстрация]</li>
<li><a href="../../screencasts.html" target="_blank">Video Tutorials and Demos for IDE NetBeans 6.x</a></li>
<li><a href="http://refcardz.dzone.com/refcardz/netbeans-java-editor-68" target="_blank">Работа с кодом в редакторе Java IDE NetBeans: справочник</a></li>
</ul>
<h3>Ресурсы по EJB</h3>
<ul>
<li><strong>Страница продукта:</strong> <a href="http://java.sun.com/products/ejb/" target="_blank">Технология Enterprise JavaBeans </a></li>
<li><strong>Загрузка спецификации:</strong> <a href="http://jcp.org/aboutJava/communityprocess/final/jsr318/index.html" target="_blank">JSR 318: EJB 3.1 Final Release</a></li>
<li><strong>Пример реализации:</strong> <a href="http://glassfish.dev.java.net/downloads/ri" target="_blank">http://glassfish.dev.java.net/downloads/ri</a></li>
<li><strong>Официальный форум:</strong> <a href="http://forums.sun.com/forum.jspa?forumID=13" target="_blank">Enterprise Technologies — Enterprise JavaBeans</a></li>
<li><strong>Учебный курс Java EE 6:</strong> <a href="http://download.oracle.com/docs/cd/E17410_01/javaee/6/tutorial/doc/bnblr.html" target="_blank">Часть IV. Компоненты уровня предприятия</a></li>
</ul>
<h3>Ресурсы по JPA</h3>
<ul>
<li><strong>Страница продукта:</strong> <a href="http://java.sun.com/javaee/technologies/persistence.jsp" target="_blank">Java Persistence API</a></li>
<li><strong>Загрузка спецификации:</strong> <a href="http://jcp.org/aboutJava/communityprocess/final/jsr317/index.html" target="_blank">JSR 317: Java Persistence 2.0 Final Release</a></li>
<li><strong>Пример реализации:</strong> <a href="http://www.eclipse.org/eclipselink/downloads/ri.php" target="_blank">http://www.eclipse.org/eclipselink/downloads/ri.php</a></li>
<li><strong>Учебный курс по Java EE 6:</strong> <a href="http://download.oracle.com/docs/cd/E17410_01/javaee/6/tutorial/doc/bnbpy.html" target="_blank">Часть VI. Сохранение состояния</a></li>
</ul>
<h3>Ресурсы по GlassFish</h3>
<ul>
<li><a href="https://glassfish.dev.java.net/docs/index.html" target="_blank">Документация GlassFish v3</a></li>
<li><a href="http://www.sun.com/offers/details/GlassFish_Tomcat.html" target="_blank">Изучение GlassFish в Tomcat</a></li>
<li><a href="https://glassfish.dev.java.net/javaee5/persistence/persistence-example.html" target="_blank">Проект GlassFish. Пример использования Java Persistence</a></li>
<li><a href="http://docs.sun.com/app/docs/doc/820-7759" target="_blank">Первые шаги: введение в платформу Java EE</a></li>
<li><a href="https://glassfish.dev.java.net/downloads/ri/" target="_blank">Загрузка примеров реализации</a></li>
</ul>
<h3>Технические статьи</h3>
<ul>
<li><a href="http://www.theserverside.com/news/1363656/New-Features-in-EJB-31" target="_blank">Новые возможности EJB 3.1</a></li>
<li><a href="http://www.ibm.com/developerworks/java/library/j-ejb1008.html" target="_blank">Практические рекомендации по EJB: безопасность компонентов сущностей</a></li>
<li><a href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/SessionFacade.html" target="_blank">Core J2EE Patterns - Фасад сеанса</a></li>
<li><a href="http://www.ibm.com/developerworks/websphere/library/techarticles/0106_brown/sessionfacades.html" target="_blank">Правила и шаблоны фасадов сеанса</a></li>
<li><a href="http://www.oracle.com/technology/sample_code/tech/java/j2ee/designpattern/businesstier/sessionfacade/readme.html" target="_blank">Пример приложения шаблона проектирования - фасад сеанса</a></li>
<li><a href="http://www.ibm.com/developerworks/websphere/library/bestpractices/using_httpservlet_method.html" target="_blank">Практические рекомендации: использование метода <code>init</code> объекта HttpServlet</a></li>
</ul>
<h3>Книги</h3>
<ul>
<li><a href="http://www.amazon.com/Beginning-Java-EE-GlassFish-Second/dp/143022889X/ref=dp_ob_title_bk" target="_blank">Начало работы с Java EE 6 с GlassFish 3</a></li>
<li><a href="http://www.amazon.com/Java-EE-GlassFish-Application-Server/dp/1849510369/ref=sr_1_1?s=books&ie=UTF8&qid=1281888153&sr=1-1" target="_blank">Java EE 6 с сервером приложений GlassFish 3</a></li>
<li><a href="http://www.apress.com/book/view/1590598954" target="_blank">Pro IDE NetBeans 6 Rich Client Platform Edition</a></li>
<li><a href="http://www.amazon.com/Real-World-Patterns-Rethinking-Practices/dp/0557078326/ref=pd_sim_b_4" target="_blank">Испытанные приемы пересмотра шаблонов Java EE Real World</a></li>
<li><a href="http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420/ref=sr_1_1?s=books&ie=UTF8&qid=1281985949&sr=1-1" target="_blank">Шаблоны архитектуры корпоративных приложений</a></li>
<li><a href="http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/ref=sr_1_1?s=books&ie=UTF8&qid=1281985959&sr=1-1" target="_blank">Разработка на основе доменов: сложность отслеживания в основе программного обеспечения</a></li>
</ul>
</div>
<br>
<h2>Ссылки</h2>
<ol>
<li id="footnote1"><a href="#1" style="text-decoration:none">^</a> Адаптация <a href="http://www.manning.com/panda/" target="_blank">EJB 3 в действии</a> Глаза 1, раздел 1.1.2: EJB как платформа.</li>
<li id="footnote2"><a href="#2" style="text-decoration:none">^</a>EJB предоставляет множество других служб. Более подробный список приведен в книге <a href="http://www.manning.com/panda/" target="_blank">EJB 3 в действии</a>, глава 1, раздел 1.3.3: получение функциональных возможностей с помощью служб EJB.</li>
</ol>
</body>
</html>