Введение в Service Data Objects

Программирование данных следующего поколения в среде Java

Если вы полагаете, что модели программирования и API J2EE принуждают разработчиков к затратам слишком большого количества времени на специфическую для технологии настройку, программирование и отладку, тогда эта статья для вас! Многие Java-разработчики скептически относятся к унификации доступа к гетерогенным данным и разочаровались в различных средах программирования, призванных решить проблему. В данной статье Java-разработчики Bertrand Portier и Frank Budinsky познакомят вас с программированием данных следующего поколения с использованием Service Data Objects (SDO).

Bertrand Portier, разработчик программного обеспечения, IBM

Bertrand Portier разрабатывает программное обеспечение для IBM. Он является ключевым участником команды разработчиков EMF, выпускающую справочную реализацию SDO на Eclipse.org. Имеет значительный опыт в J2EE. Участвует в разработке продуктов и предложений IBM в области web-служб и помогает клиентам IBM в разработке распределенных приложений.


developerWorks Professional author
        level

Frank Budinsky, руководитель проекта Eclipse EMF, IBM

Frank Budinsky - руководитель проекта Eclipse Modeling Framework на Eclipse.org - является соавтором и реализатором платформы EMF, включая справочную реализацию SDO. Является инженером в IBM's Software Group и разрабатывает платформы и генераторы в течение нескольких лет. Является ведущим автором официальной книги по EMF: Eclipse Modeling Framework, A Developer's Guide.



28.09.2004

Проще говоря, SDO представляет собой среду разработки приложений обработки данных, состоящую из архитектуры и API. SDO выполняет следующие задачи:

  • Упрощает J2EE-модель программирования данных.
  • Абстрагирует данные в ориентированную на службы архитектуру (SOA).
  • Унифицирует разработку приложений обработки данных.
  • Поддерживает и интегрирует XML.
  • Включает в себя J2EE-шаблоны и лучшие примеры использования.

В этом введении в SDO мы попытаемся объяснить мотивы использования SDO и различия между SDO и другими спецификациями. Затем мы опишем компоненты, составляющие SDO. Наконец, мы получим шанс увидеть SDO в действии при рассмотрении простого SDO-приложения.

Почему SDO?

Первым вопросом, который задаст большинство разработчиков о Service Data Objects (SDO), будет "почему". Не является ли J2EE достаточно большим и сложным (и сложным в изучении)? Кроме того, существуют же другие системы, поддерживающие XML на Java-платформе. К счастью ответ, который должен осчастливить большинство из нас, один: SDO возник как средство упрощения J2EE-модели программирования данных, предоставляя таким образом J2EE-разработчикам больше времени на работу с бизнес-логикой их приложений.

Система Service Data Objects предоставляет унифицированную среду для разработки приложений обработки данных. С SDO вам не обязательно изучать зависящий от используемой технологии API для обращения и обработки данных. Вы должны знать только один API - SDO API, который позволит вам работать с данными из различных источников данных, включая реляционные базы данных, EJB-компоненты управления данными, XML-страницы, Web-службы, Java Connector Architecture, страницы JavaServer Pages и др.

Отметим, что мы используем слово среда (framework). Аналог - среда Eclipse. Eclipse спроектирован так, что инструментальные средства могут быть интегрированы благодаря их цельной и расширяемой природе. SDO является аналогией в том смысле, что предоставляется среда, в которую могут быть интегрированы приложения и эти приложения будут согласованы с SDO-моделью.

В отличие от некоторых других моделей интеграции данных, SDO не останавливается на абстракции данных. Среда SDO содержит также большое количество J2EE-шаблонов и примеров использования, что облегчает включение проверенной архитектуры и дизайна в ваши приложения. Например, большинство современных Web-приложений не связаны (и не могут быть) с системой хранения данных 100% времени; поэтому SDO поддерживает разъединенную модель программирования. Кроме того, современные приложения становятся очень сложными, работающими на нескольких уровнях предприятия. Как будут храниться данные? Передаваться? Представляться конечному пользователю в GUI-программах? Программная модель SDO предписывает шаблоны использования, что дает возможность четкого разделения каждого из этих уровней.

Повсеместно используемым в распределенных приложениях становится стандарт XML. Например, XML Schema (XSD) применяется для определения бизнес-правил в формате данных приложения. Также XML сам по себе используется для облегчения взаимодействия: Web-службы используют основанный на XML протокол SOAP в качестве технологии обмена сообщениями. XML является очень важной сущностью в SDO, поддерживается и интегрируется в нее.


Сравнение технологий

Как было отмечено ранее, SDO не является единственной технологией, предлагаемой для решения проблем интеграции данных в распределенных приложениях. В данном разделе мы рассмотрим, как SDO выглядит на фоне аналогичных сред программирования, таких как JDO, JAXB и EMF.

SDO и WDO

Web Data Objects, или WDO - это название ранней редакции SDO, поставляемой с IBM WebSphere Application Server 5.1 и IBM WebSphere Studio Application Developer 5.1.2. Если вы работали с WebSphere Studio 5.1.2, вы уже должны быть определенным образом знакомы с SDO, хотя возможно привыкли видеть их обозначенными как WDO, например, в названиях библиотек. Забудьте про WDO, они сейчас называются SDO!

SDO и JDO

JDO означает Java Data Objects. JDO был стандартизирован через Java Community Process (JCP) с версией 1.0 и технической версией 1.0.1 в мае 2003. Для версии 2.0 сформировалась экспертная группа JCP. JDO представляет собой программирование данных в среде Java и предоставляет общий API доступа к данным, хранящимся в источниках данных различного типа; например, базах данных, файловых системах или системах обработки транзакций. JDO сохраняет связи между Java-объектами (графами) и одновременно разрешает параллельный доступ к данным.

Назначение JDO аналогично назначению SDO в том смысле, что обе технологии хотят упростить и унифицировать программирование данных Java с тем, чтобы разработчики больше концентрировались на бизнес-логике, а не на используемых технологиях. Однако, главным отличием между ними является то, что JDO рассматривает только вопрос персистентности (на уровне данных J2EE и на уровне корпоративной информационной системы (EIS)), тогда как SDO охватывает более широкий круг вопросов и представляет данные, которые могут передаваться между уровнями J2EE, например, между уровнем представления и бизнес-уровнем.

Интересно что SDO может использоваться совместно с JDO. При этом JDO является источником данных, к которому может обращаться SDO, реализуя модель проектирования Data Transfer Object (DTO). SDO также может использоваться совместно с EJB-компонентами, управляющими данными, и Java Connector Architecture (JCA) для предоставления унифицированного доступа к данным.

SDO и EMF

EMF - это аббревиатура Eclipse Modeling Framework. Основываясь на модели данных, описанной с использованием Java-интерфейсов, XML Schema или диаграмм классов UML, EMF генерирует унифицированную метамодель (называемую Ecore), которая вместе со средой может быть использована для создания высококачественной реализации модели. EMF обеспечивает персистенцию, очень эффективный оригинальный API управления объектами и уведомляющую об изменениях среду. EMF включает также оригинальные повторно используемые классы для построения редакторов EMF-модели.

И EMF и SDO имеют дело с представлением данных. Фактически, справочная реализация SDO от IBM, которую мы будем использовать далее в данной статье, является EMF-реализацией SDO. Генерация кода EMF используется даже при создании некоторых SDO-реализаций, основанных на UML-описании модели SDO. По существу реализация SDO представляет собой тонкий уровень (фасад) над EMF и пакетируется и поставляется как часть EMF-проекта. См. раздел Ресурсы для дополнительной информации по EMF.

SDO и JAXB

JAXB - это аббревиатура Java API for XML Data Binding. JAXB 1.0 был выпущен группой JCP в январе 2003. Экспертная группа JCP уже подготовила проект версии 2.0. JAXB посвящен связыванию XML-данных; т.е. представлению XML-данных в виде Java-объектов в памяти. JAXB освобождает вас от необходимости самостоятельного синтаксического разбора или создания XML-документов, действуя как среда XML-связывания для Java. (Фактически вы освобождаетесь вообще от работы с XML.) JAXB выполняет маршаллизацию/сериализацию (Java в XML) и обратный процесс (XML в Java) вместо вас.

SDO определяет среду Java-связывания и идет на шаг дальше. JAXB уделяет внимание только связыванию Java-to-XML, в то время как XML - не единственный тип данных, связанный с SDO. Как было отмечено выше, SDO предоставляет унифицированный доступ к данным различных типов, одним из которых является XML. SDO определяет также статический и динамический API, а JAXB определяет только статическое связывание.

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

SDO и ADO .NET

Обозначение ADO использовалось как аббревиатура ActiveX Data Objects, но в контексте .NET это уже не так. ADO .NET обеспечивает унифицированный доступ к данным между различными уровнями платформы .NET.

ADO .NET и SDO предназначены для решения одинаковых задач - поддержка XML и распределенных по нескольким уровням приложений. Главным различием между этими двумя технологиями, кроме технических, является то, что ADO .NET предназначена для платформы Microsoft .NET и является проприетарной технологией, в то время как SDO предназначена для платформы Java и стандартизирована через Java Community Process.


SDO-компоненты

В данном разделе мы рассмотрим архитектуру SDO. Мы опишем каждый из компонентов, составляющих платформу, и объясним принципы их совместной работы. Сначала мы рассмотрим три компонента, являющиеся "концептуальными" для SDO. Они не имеют соответствующих интерфейсов в API.

SDO-клиенты

SDO-клиенты используют платформу SDO для работы с данными. Вместо использования различных API и платформ они применяют программную модель и API SDO. SDO-клиенты работают с графами данных SDO (см. рисунок 1) и не нуждаются в знании особенностей хранения и сериализации используемых данных.

Промежуточные службы данных

Промежуточные службы данных (DMS) отвечают за создание графа данных из источника (источников) данных и обновление источников данных, основываясь на изменениях графа данных. Платформа для работы этих служб не является предметом рассмотрения спецификации SDO 1.0. Другими словами, в SDO 1.0 не говорится о конкретных DMS. Примерами DMS являются JDBC DMS, компонент управления данными EJB DMS, XML DMS и т.д.

Источники данных

Источники данных не ограничены базами данных. Данные могут храниться в любом формате. Только DMS обращается к источникам данных, SDO-приложения - нет. SDO-приложения могут работать только с объектами графов данных.

Каждый из следующих компонентов соответствует Java-интерфейсу в программной модели SDO. Справочная реализация SDO (см. раздел Ресурсы) предоставляет EMF-реализации этих интерфейсов.

Объекты данных

Объекты данных являются фундаментальными объектами SDO. Фактически именно они являются объектами данных служб, которые фигурируют в названии самой спецификации. Объекты данных - это SDO-представление структурированных данных. Они являются родовыми объектами и предоставляют общее видение структурированных данных, сформированное службами DMS. Если, например, для JDBC DMS необходимо знать об используемой технологии хранения (например, реляционные базы данных), способах доступа к данным и методах их конфигурирования, то для SDO-клиентов ничего этого не надо. Объекты данных хранят свои "данные" в свойствах (более подробно о свойствах далее) и предоставляют удобные методы создания и удаления (createDataObject() с различными параметрами и delete()), а также методы для получения их типа (класс реализации, название, свойства и пространство имен). Объекты данных связываются вместе и содержатся в графах данных.

Графы данных

Графы данных обеспечивают контейнер для дерева объектов данных. Графы данных создаются службами DMS для работы с ними SDO-клиентов. Если графы данных изменяются, они передаются обратно в DMS для изменения источника данных. SDO-клиенты могут просматривать граф данных, читать и изменять его объекты данных. SDO представляет собой изолированную архитектуру, поскольку SDO-клиенты не связаны с DMS и источниками данных; они видят только граф данных. К тому же, граф данных может состоять из объектов, представляющих данные из разных источников данных. Граф данных содержит корневой объект данных, связанные с ним остальные объекты данных и суммарный отчет по изменениям (более подробно о суммарных отчетах далее). При передаче между компонентами приложения (например, между заказчиком Web-службы и провайдером во время инициирования службы), передаче в DMS, или сохранении на диск графы данных сериализуются в XML. Для сериализации спецификация SDO предоставляет XML Schema. На рисунке 1 изображен граф данных SDO.

Рисунок 1. Граф данных SDO
Граф данных SDO

Суммарный отчет по изменениям

В графы данных включаются суммарные отчеты по изменениям, которые используются для представления изменений, произведенных в полученном от DMS графе данных. Первоначально они пустые (когда граф данных передается клиенту), и заполняются по мере проведения изменений. Суммарные отчет по изменениям используются службами DMS во время обновления базы данных для фиксации изменений в источнике данных. Предоставляя списки измененных свойств (вместе со старыми значениями), а также списки созданных в графе данных и удаленных из него объектов, суммарные отчеты изменений дают возможность службам DMS эффективно и последовательно обновлять источники данных. Информация добавляется в отчет графа данных только при активированной функции протоколирования изменений. Для DMS предоставляются методы включения и отключения протоколирования. Более подробно мы рассмотрим эти вопросы в разделе с примером приложения.

Свойства, типы и последовательности

Объекты данных хранят свою информацию в наборе свойств. Каждое свойство имеет тип, являющийся либо типом атрибута, например, примитивным типом (int) или общеупотребительным типом данных (Date), либо типом другого объекта данных (если указана ссылка). Каждый объект данных предоставляет методы доступа для чтения и записи своих свойств (getters и setters). Предоставляются несколько перегруженных версий этих методов, разрешающих доступ к свойствам по их имени (String), по номеру (int) или по собственно мета-объекту свойства. Метод доступа с String поддерживает также XPath-синтаксис обращения к свойствам. Например, вы можете вызвать метод get("department[number=123]") объекта данных компании для обращения к первому отделу с номером 123. Последовательности являются более расширенными объектами. Они позволяют указывать гетерогенные списки пар свойство-значение.


SDO и пример установки

Достаточно концепций и теорий. Настало время для практических действий. Хорошие новости - вы можете использовать SDO сегодня, причем свободно! В данном разделе мы рассмотрим пример приложения SDO, выполняющегося на справочной реализации SDO от IBM, поставляемой как часть Eclipse Modeling Framework (EMF). Для начала мы опишем процесс установки EMF 2.0.1 (включая SDO), затем - настройку примера приложения, рассматриваемого в данной статье.

Установка EMF 2.0.1

Вы можете пропустить этот раздел, если EMF у вас уже установлен или вы знаете, как его установить.

IBM-реализация SDO 1.0 поставляется с EMF 2.0.1. Для работы с SDO вы должны установить EMF 2.0.1. Можно использовать менеджер обновлений eclipse, описанный на сайте EMF, либо выполнить указанные ниже действия.

Реализация SDO 1.0 доступна также в EMF 2.0.0.

На домашней странице EMF в разделе Quick Nav вы можете найти список ссылок для загрузки. Необходимо выбрать вариант загрузки "v2.x: EMF and SDO". Перед установкой EMF ознакомьтесь с требованиями для инсталляции. По сути, вам необходимо иметь установленными Eclipse 3.0.1 и Java Development Kit (JDK). Выберите версию EMF 2.0.1. Как тип пакета мы рекомендуем "All": emf-sdo-xsd-SDK-2.0.1.zip; при этом вы получите исходные коды, исполняемые файлы и документацию в одном архиве. При желании вы можете выбрать для загрузки минимальный пакет с SDO, который называется "EMF & SDO RT": emf-sdo-runtime-2.0.1.zip.

Разархивируйте zip-файл в каталог с eclipse (файлы в архиве структурированы в виде eclipse/plugins/...).Для проверки успешной установки EMF запустите Eclipse и выберите Help>About the Eclipse Platform. Нажмите кнопку Plug-in Details. Убедитесь, что подключаемые модули org.eclipse.emf.* имеют версию 2.0.1. Следующие шесть подключаемых модулей имеют отношение к SDO:

  • org.eclipse.emf.commonj.sdo
  • org.eclipse.emf.ecore.sdo
  • org.eclipse.emf.ecore.sdo.doc
  • org.eclipse.emf.ecore.sdo.edit
  • org.eclipse.emf.ecore.sdo.editor
  • org.eclipse.emf.ecore.sdo.source

Только два модуля org.eclipse.emf.commonj.sdo и org.eclipse.emf.ecore.sdo необходимы во время исполнения. Вы можете увидеть в списке только их (если выбрали при установке только подключаемые модули времени исполнения). На этом установка EMF заканчивается.

Установка примера SDO-приложения

Следующий шаг - добавление рассматриваемого в статье примера SDO-приложения в вашу рабочую среду. Выполните следующие действия:

  1. Запустите Eclipse и создайте новый Plug-In Project.
  2. Назовите проект SDOSample и создайте Java-проект с каталогами src для исходных кодов и bin для генерируемых файлов.
  3. Нажмите Next.
  4. Снимите отметку с варианта "Generate the Java class that controls the plug-in's life cycle" и нажмите Finish.

Затем, щелкните по иконке Code, расположенной в верхней или нижней части данной статьи (или перейдите в раздел Загрузка), для получения файла j-sdoSample.zip. Разархивируйте его в каталог SDOSample (Используя пункт меню проекта в Eclipse: Import...>Zip file). Убедитесь, что структура папки не нарушилась и существующие файлы перезаписались. Проект SDOSample заполнился файлами из j-sdoSample.zip.

Примечание: SDOSample поставляется как проект подключаемого модуля Eclipse, так что вы не должны сами устанавливать библиотечные зависимости. Впрочем, пример является обычным Java-кодом, поэтому его можно запустить как отдельное приложение с условием, что CLASSPATH включает ссылки на библиотеки EMF и SDO (JAR-файлы).

Ваше рабочее окружение должно теперь выглядеть аналогично показанному на рисунке 2.

Рисунок 2. Рабочая среда Eclipse
Рабочая среда Eclipse

Теперь мы готовы начать работу с нашим примером SDO-приложения.


Простое SDO-приложение

Рассматриваемый нами в оставшейся части статьи пример приложения обладает ограниченной функциональностью, но он поможет нам лучше понять SDO. Приложение состоит из двух частей, разделенных на два соответствующих пакета: dms и client.

SDO 1.0 не определяет стандарт DMS API. Поэтому в этом примере мы создали наш собственный DMS-интерфейс, предоставляющий два метода. Это показано в листинге 1.

Листинг 1. DMS-интерфейс
/**
 * Простой Data Mediator Service (DMS), который строит
 * графы данных SDO по сотрудникам (Employees) и изменяет
 * источник данных в соответствии с графом данных. 
 */
public interface EmployeeDMS
{
  /**
   * @param employeeName - имя сотрудника.
   * @return - граф данных SDO с объектами данных для
   * менеджера этого сотрудника, самого сотрудника,
   * и "сотрудников" этого сотрудника.
   */
  DataGraph get(String employeeName);

  /**
   * обновляет источник данных в соответствии с dataGraph.
   * @param dataGraph - граф данных, используемый для обновления
   * источника данных.
   */
  void update(DataGraph dataGraph);
}

Клиент создает экземпляр DMS и вызывает его метод get() для конкретных сотрудников: The Big Boss, Wayne Blanchard и Terence Shorter. Выводит информацию по этим сотрудникам на экран в удобной для пользователя форме, затем изменяет информацию об отделе для Terence Shorter и его сотрудников. И, наконец, вызывает метод DMS update(), передав в него измененный граф данных для Terence Shorter.

Обратите внимание, что в демонстрационных целях мы не реализуем компонент источника данных. Вместо этого DMS обладает "жестко закодированными" знаниями о том, как построить граф данных в зависимости от запроса. На рисунке 3 изображена иерархия сотрудников, используемая DMS.

Рисунок 3. Сотрудники Big Boss Corporation
Сотрудники Big Boss Corporation

Как видите, виртуальная компания состоит из четырех сотрудников. Иерархия компании следующая:

  • The Big Boss не имеет менеджера, ему напрямую подчинен Terence Shorter.
  • Terence Shorter имеет менеджера в лице The Big Boss и двух подчиненных в лице John Datrane и Miles Colvis.
  • John Datrane имеет менеджера в лице Terence Shorter и не имеет подчиненных.
  • Miles Colvis имеет менеджера в лице Terence Shorter и не имеет подчиненных.

Выполнение примера

Для запуска примера приложения кликните правой кнопкой мышки на SDOClient.java и выберите Run>Java application. На экране вы должны увидеть информацию, аналогичную листингу 2.

Листинг 2. Выводимая приложением на экран информация
********* EMPLOYEE INFORMATION *********

Name: John Datrane
Number: 4
Title: Mr.
Department: Procurement
Is manager?: no

DIRECT MANAGER:

Name: Terence Shorter
Number: 2
Title: Mr.
Department: Financing
Is manager?: yes

****************************************

NO INFORMATION AVAILABLE ON EMPLOYEE Wayne Blanchard

********* EMPLOYEE INFORMATION *********

Name: Terence Shorter
Number: 2
Title: Mr.
Department: Financing
Is manager?: yes

DIRECT MANAGER:

Name: The Big Boss
Number: 1
Title: Mr.
Department: Board
Is manager?: yes

DIRECT EMPLOYEES:

Name: Miles Colvis
Number: 3
Title: Mr.
Department: Accounting
Is manager?: no

Name: John Datrane
Number: 4
Title: Mr.
Department: Procurement
Is manager?: no

[Total: 2]
****************************************

DMS updating Terence Shorter
 (changed department from "Financing" to "The new department")
DMS updating Miles Colvis
 (changed department from "Accounting" to "The new department")
DMS updating John Datrane
 (changed department from "Procurement" to "The new department")

Теперь рассмотрим работу каждого из компонентов приложения.


Клиент

SDO-клиент создает экземпляр DMS и получает из него графы данных для различных сотрудников. После получения графа данных он перемещается по дереву объектов и обращается к объектам через корневой элемент (используя динамический API SDO), как показано ниже:

// Получение SDO DataGraph от DMS.
DataGraph employeeGraph = mediator.get(employeeName);
...
// Получение корневого объекта
DataObject root = employeeGraph.getRootObject();
...
// Получение сотрудника конкретного менеджера
employee = theManager.getDataObject("employees.0");

Затем клиент вызывает динамический API SDO-доступа для получения информации из объектов данных и вывода ее на экран:

System.out.println("Name: " + employee.getString("name"));
System.out.println ("Number: " + employee.getInt("number"));
...
System.out.println ("Is manager?: " + 
  (employee.getBoolean("manager") ? "yes" : "no") + "\n");

Мы увидели, как клиент может получить информацию (для чтения), а как насчет записи? Более конкретно - как клиент может изменить объекты? Для изменения объектов SDO-клиенты обычно используют методы доступа по записи DataObject. Например, вот как клиент может изменить граф данных, полученный для сотрудника Terence Shorter:

employee.setString("department", newDepartmentName);

Обратите внимание, что клиент не вызывает методы для ведения протокола. Об этом заботится DMS, вызывая методы beginLogging() и endLogging() суммарного отчета об изменениях графа данных.


Граф данных

Формат данных (модель) графа данных может рассматриваться как контракт между DMS и клиентом. В данном формате клиент ожидает информацию от DMS и DMS знает, как ее сформировать (а также принимает в этом формате информацию от клиента для обновления источника данных). Если вы знакомы с технологиями XML и Web-служб, вы можете рассматривать модель графа данных как XML Schema (XSD), определяющую ваши объекты данных. Тогда граф данных сам по себе будет аналогией экземпляра XML-документа. Фактически XML Schema - это один из способов определения SDO-модели.

Отметим, что графы данных и их модели всегда могут сериализироваться в XML. В SDOClient.java установите переменную debug в true и вы должны увидеть сериализованную версию выводимого на экран графа данных во время исполнения. Полученная на экране информация должна выглядеть примерно так, как показано в листинге 3.

Листинг 3. Сериализованная версия графа данных
<?xml version="1.0" encoding="UTF-8"?>
<sdo:datagraph xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:company="http://com.example.company.ecore"
  xmlns:sdo="commonj.sdo"
  xmlns:sdo_1="http://www.eclipse.org/emf/2003/SDO">
  <changeSummary>
    <objectChanges key="#//@eRootObject">
      <value xsi:type="sdo_1:EChangeSummarySetting>
        featureName="department" dataValue="Board"/>
    </objectChanges<
  </changeSummary>
  <company:Employee name="The Big Boss"
    number="1" department="The new department" title="Mr."
    manager="true">
    <employees name="Terence Shorter" number="2"
      department="The new department" title="Mr." manager="true"/>
      <employees name="Miles Colvis" number="3"
        department="The new department" title="Mr."/>
      <employees name="John Datrane" number="4"
        department="The new department" title="Mr."/>
    </employees>
  </company:Employee>
</sdo:datagraph>

В данном примере граф данных состоит из объектов данных Employee (и суммарного итога об изменениях). Employee имеет такие атрибуты как name, number, department, title, manager (другой сотрудник, являющийся менеджером данного сотрудника) и employees (другие сотрудники, подчиняющие данному сотруднику). В этом примере, когда модель сотрудника жестко закодирована в исходном коде, возвращаемый из DMS граф данных всегда будет представлен как менеджер сотрудника (при его наличии), запрошенный сотрудник и его/ее прямые подчиненные (при наличии таковых).


DMS: Построение графа

SDO 1.0 не определяет DMS API, который мог бы включать процедуры дизайна и создания самой модели графа данных. Дизайн графа данных может быть предметом рассмотрения отдельной статьи, поскольку существует множество сценариев при проектировании доступа к источникам данных.

Для данного примера мы будем использовать модель сотрудника, определяемого службами DMS при помощи EMF API. Пример графа данных не имеет документа модели, такого, как например XSD. Утверждение, что объекты данных генерируются динамически, означает то, что не генерируются Java-классы Employee. При использовании статических методов противоположное утверждение было бы истинно.

DMS получают свою информацию из различных источников данных при помощи различных API доступа к данным (JDBC, SQL и т.д.). Однако, как только информация получена из хранилища (в данном примере она жестко закодирована в исходном коде), DMS использует EMF API (eGet, eSet) вместо SDO API для построения графа данных объектов данных. Такой подход дает оптимальную производительность, но имеет недостаток - отсутствие переносимости между SDO-реализациями.

В тех случаях, когда производительность не является основным требованием, аналогичный DMS-дизайн может быть реализован с использованием SDO API. В данном случае кэшированные мета-объекты в DMS-классе (employeeClass, employeeNameFeature и т.д.) могут иметь тип commonj.sdo.Type и commonj.sdo.Property, вместо EMF-типов EClass, EAttribute и EReference. Более того, если производительность вообще не важна, может использоваться удобный основанный на строковом типе SDO API (например, setBoolean(String path, boolean value)), устраняя тем самым необходимость в кэшировании мета-объектов. К сожалению, при своем удобстве такое решение будет работать значительно медленнее.

Приведенный ниже фрагмент кода показывает, как определяется модель Employee в SimpleEmployeeDataMediatorImpl.java. Это еще не исходный код для построения SDO-объектов, а только код модели SDO-объектов:

protected EClass employeeClass;
protected EAttribute employeeNameFeature;
protected EReference employeeEmployeesFeature;
...

employeeClass = ecoreFactory.createEClass();
employeeClass.setName("Employee");

EAttribute employeeNameFeature = ecoreFactory.createEAttribute();
...
    
// сотрудники (подчиняющиеся сотруднику)
employeeEmployeesFeature = ecoreFactory.createEReference();
employeeEmployeesFeature.setContainment(true);
...

EPackage employeePackage = ecoreFactory.createEPackage();
employeePackage.getEClassifiers().add(employeeClass);
...

Обратите внимание, что мы вызываем setContainment со значением true в employees EReference, следовательно каждый сотрудник будет содержать своих подчиненных. Если этого не сделать, подчиненные сотрудники не будут в (то есть, содержаться в) графе данных и в суммарный отчет об изменениях не будут вноситься изменения сотрудников, отличных от корневого объекта графа.

Моделирование SDO

Сейчас вы наверное думаете, "Это конечно интересно, но все это даст мне EMF-объекты, а не SDO-объекты данных. В чем здесь хитрость?" Да, это вопрос по существу. Employee EClass принадлежит employeePackage EPackage, который вызывается так:

// Генератор для этого пакета формирует SDO-объекты
employeePackage.setEFactoryInstance(
  new DynamicEDataObjectImpl.FactoryImpl());

Во время исполнения генератор будет создавать объекты с типом DynamicEDataObjectImpl, которые реализуют интерфейс DataObject (т.е. SDO-объекты данных), а не интерфейс по умолчанию DynamicEObjectImpl, который создает только обычные EMF-объекты. Это подчеркивает взаимосвязь между SDO и EMF-объектами: SDO-объекты - это просто EMF-объекты, реализующие также SDO-интерфейс DataObject. Фактически реализация этих дополнительных методов производится делегированием их в ядро самой EMF.

Создание экземпляров SDO

Теперь, поскольку мы имеем модель наших объектов данных, мы можем создать экземпляры Employee и установить различные их свойства. Как отмечалось выше, для увеличения производительности мы будем использовать EMF API.

EObject eObject = EcoreUtil.create(employeeClass);

// Примечание: мы можем преобразовать объект в тип DataObject,
// но выбираем использование EObject API.
eObject.eSet(employeeNameFeature, name);
eObject.eSet(employeeNumberFeature, new Integer(number));
... ...

Мы можем затем "связать" сотрудников вместе при помощи ссылок на них, например:

((List)bigBoss.eGet(employeeEmployeesFeature)).add(terence);

После создания объектов данных необходимо подключить их к графу данных. Для этого вызываем метод графа данных setRootObject(), передавая ему объект данных, который будет корневым элементом, в данном случае Employee The Boss.

EDataGraph employeeGraph = SDOFactory.eINSTANCE.createEDataGraph();
... ...
employeeGraph.setERootObject(rootObject);

Последним действием перед возвратом графа данных должен быть запуск протоколирования изменений. Если вы хотите пользоваться возможностями SDO, перед какими-либо изменениями графа данных должен быть вызван метод beginLogging() его суммарного отчета об изменениях. Его обычное действие - начать слежение за изменениями после сброса всех предыдущих изменений.

// Вызов beginLogging() для заполнения суммарного отчета об изменениях
// при проведении изменений в графе данных.
// Вызывать beginLogging() и endLogging() должен DMS,
// а не клиент.
employeeGraph.getChangeSummary().beginLogging();

Другой задачей DMS (определенной в интерфейсе EmployeeDataMediator) является обновление источника данных на основе изменений графа данных, предоставленного SDO-клиентом.


DMS: обновление источников данных

Для обновления источников данных DMS должны использовать мощные возможности SDO, в частности его суммарные отчеты об изменениях. Существует много вариантов использования суммарных отчетов об изменениях. В данном примере мы просматриваем все объекты данных, на которые есть ссылка в суммарном отчете об изменениях и получаем оттуда новые объекты данных.

Листинг 4. Обновление источников данных DMS в соответствии с графом данных
/**
 * Обновление источников данных DMS для отображения
 * изменений в графе данных.
 * Поскольку данный DMS не имеет реальных источников данных и, следовательно,
 * ему нечего обновлять, мы просто перемещаемся по суммарному отчету
 * об изменениях и выводим на экран (распечатываем) эти изменения.
 */
public void update(DataGraph dataGraph)
{
  ChangeSummary changeSummary = dataGraph.getChangeSummary();
 
  // Вызов endLogging для завершения протоколирования изменений.
  // Вызывать beginLogging() и endLogging() должен DMS,
  // а не клиент.
  changeSummary.endLogging();
 
  // Использование SDO-метода ChangeSummary getChangedDataObjects().
  List changes = changeSummary.getChangedDataObjects();
  for (Iterator iter = changes.iterator(); iter.hasNext();)
  {
    DataObject changedObject = (DataObject)iter.next();
    System.out.print("DMS updating " +
      changedObject.getString("name"));

    for (Iterator settingIter = changeSummary.getOldValues(
      changedObject).iterator(); settingIter.hasNext();)
    {
      ChangeSummary.Setting changeSetting =
        (ChangeSummary.Setting)settingIter.next();
      Property changedProperty = changeSetting.getProperty();
      Object oldValue = changeSetting.getValue();
      Object newValue = changedObject.get(changedProperty);

      System.out.print(" (changed: " + changedProperty.getName() +
        " from "\" + oldValue + "\" to "\" + newValue + "\")");
      // Если бы не наш простой пример, мы должны были бы 
      //обновлять источники данных здесь.
    }

    System.out.println();
  }
}

В данном примере нет реального источника данных. В действительности в этом методе должен обновляться источник данных.

Первым действием, которое выполняет DMS после получения от клиента графа данных для обновления источника данных, является вызов метода endLogging() суммарного отчета об изменениях графа данных. При этом отключается протоколирование изменений, завершая тем самым суммарный отчет об изменениях, проведенных в графе данных после вызова метода beginLogging() (обычно после создания графа). Этот отчет предоставляется в формате, позволяющем DMS эффективно и последовательно обновить источники данных. Существует три типа изменений:

  • Изменение объектов содержит ссылки на объекты данных в графе данных, чьи свойства были изменены, вместе с измененными свойствами и старыми значениями этих свойств. Старые значения могут быть использованы DMS для проверки того, что источник данных тем временем не был изменен кем-либо еще.
  • Создание объектов содержит объекты данных, добавленные в граф данных. Эти объекты предоставляют новые данные, которые должны быть добавлены к структуре источника данных.
  • Удаление объектов содержит объекты данных, которые были удалены из графа данных. Эти объекты предоставляют данные, которые должны быть удалены из структуры источника данных.

Обратите внимание, что для инспектирования изменений графа данных мы использовали стандартный SDO API. Мы могли бы, впрочем, использовать EMF API ChangeDescription (вместо SDO ChangeSummary). В данном примере при обновлении простых атрибутов потеря производительности не была бы значительной. В других ситуациях, например при изменении множества свойств, применение EMF API могло бы радикально улучшить производительность. Допустим, например, что мы удаляем одного сотрудника из списка, состоящего из нескольких сотен сотрудников. В этом случае ChangeSummary предоставляет доступ к старому значению, то есть к старому списку из нескольких сотен сотрудников. Интерфейс EMF ChangeDescription, с другой стороны, предоставляет более точную информацию, например, "удалить сотрудника с конкретным индексом", которая может быть намного более полезной.

Отметим также, что в данном примере есть только изменения в суммарном отчете об изменениях и нет удалений и добавлений. Если вы поработаете с реализацией SDO и удалите объекты из графа данных, вы обнаружите элементы, имеющие тип objectToAttach. Это реальное название EMF ChangeDescription для удаленных объектов. Они представляют собой удаленные объекты данных, которые необходимо присоединить к графу данных снова при отмене операции удаления (rollback). То есть objectsToAttach == deleted objects.


Отладка приложения

Если в примере приложения вы установите значение переменной debug в true, это позволит выполнять вызовы, подобные приведенному ниже, и даст вам возможность увидеть сериализированную версию графа данных.

((EDataGraph) dataGraph).getDataGraphResource().save(System.out, null);

Вы можете также использовать среду отладки Eclipse. Например, мы рекомендуем установить точку прерывания в SDOClient.java на строке 110 и произвести отладку SDOClient (как Java-приложения). Вы сможете в целях отладки увидеть граф данных в памяти (в Variables) вместе с его объектами данных (The Boss, Terrence Shorter и др.), как показано на рисунке 4.

Рисунок 4. Просмотр объектов данных в режиме отладки
Просмотр объектов данных в режиме отладки

Таким же способом можно увидеть суммарный отчет об изменениях, как показано на рисунке 5.

Рисунок 5. Просмотр суммарного отчета об изменениях в режиме отладки
Просмотр суммарного отчета об изменениях в режиме отладки

Показанные выше снимки экрана выглядят сложными и вы, возможно, не найдете их полезными на данном этапе. Но вы сможете вернуться к ним позже при отладке вашего SDO-приложения и просмотре содержимого ваших объектов данных и суммарных отчетов об изменениях.


Заключение

В данной статье мы сделали обзор технологии SDO и ее возможностей. Мы рассмотрели пример приложения, использующего некоторые из возможностей SDO. Для получения дополнительной информации используйте документацию по SDO API в системе помощи Eclipse. Спецификация все еще развивается и улучшается. Например, SDO 1.0 акцентирует внимание на SDO с точки зрения клиента и не определяет DMS API. SDO в настоящее время проходит процедуру стандартизации через JCP, так что следите за объявлениями. Поскольку SDO является очень гибкой технологией, будет существовать множество решений, которые вы должны будете принять в процессе проектирования приложения SDO. Эти решения будут влиять на производительность и возможность повторного использования. Поэтому перед кодированием вы должны хорошо проанализировать шаблоны применения и характеристики данных вашего приложения.


Загрузка

ОписаниеИмяРазмер
Образец кодаj-sdoSample.zip---

Ресурсы

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Технология Java, SOA и web-сервисы
ArticleID=96369
ArticleTitle=Введение в Service Data Objects
publish-date=09282004