 | Уровень сложности: простой Хардип Сингх (Hardeep Singh), инструментарий разработчика DB2 XML, миграция приложений DB2 XML, IBM
06.05.2008 Главная цель XML - сделать процесс разработки приложений простым, дешевым, переносимым и высококачественным. XML-программирование принесло почти такой же радикальный сдвиг в принцип разработки приложений в этом десятилетии, какой принесли объектные методологии в предыдущие десять лет. В первой статье данной серии по программированию XML для IBM® DB2® под Linux® UNIX® и Windows® вы узнаете об основах модели данных в XML и о преимуществах, которые вы можете получить для своей среды программирования, по сравнению с использованием "чисто" объектной модели.
Введение
Как указано в рекомендациях w3, некоторые цели создания XML имеют отношение к разработке приложений:
- "XML будет поддерживать широкий спектр приложений".
- "Писать программы, которые обрабатывают XML-документы, будет просто".
.
Пока много внимания уделялось читаемости, сериализации и транспортировке, задача разработки приложений не наделала столько шуму.
Данная статья является первой в серии статей, показывающей влияние, которое оказал XML на разработку приложений, на трех уровнях:
- В части 1 сформулированы предпосылки для применения XML в разработке приложений, чтобы сделать этот процесс простым, дешевым, переносимым и высококачественным. XML-программирование произвело почти такой же радикальный сдвиг в принцип разработки приложений в этом десятилетии, какой произвели объектные методологии в предыдущие десять лет.
- В Части 2 мы сосредоточимся на роли базы данных. В данной статье мы уделим внимание функциональности и DB2 9 (изначально под кодовым названием Viper), и Viper 2. Вы узнаете:
- Как новая среда хранения XML и запросов встраиваются в модель данных XML уровня приложений.
- Почему схемы вашей базы данных становятся проще и естественнее, когда вы адаптируетесь к новой основанной на XML архитектуре разработки приложений.
- Почему запросы XML-данных в базе данных не отличаются от запросов данных в приложении.
- И, наконец, как сочетать реляционные данные с XML-данными, чтобы объединить сильные стороны обеих технологий.
- В Части 3 мы поговорим о клиенте, обратив внимание на XML-технологии, используемые в Web-браузерах и Web-серверах: Ajax, XSLT, SVG, Comet, XML-каналы и mashup-приложения. Вы узнаете, как создавать каналы и Web-сервисы в базе данных, запрашивать и объединять их на уровне приложения и затем отображать в браузерах клиента.
- Четвертая статья объединяет все эти технологии и предоставляет работающий пример из практики.
 |
Основы модели данных в XML
Традиционно XML использовали для определения метаданных бизнес-документов. Для управления этими метаданными в приложении используется объектная модель документа (document object model, DOM). Если мы посмотрим на DOM, то увидим, что она обеспечивает объектный интерфейс для иерархической структуры данных XML, а программный интерфейс DOM управляет этой иерархией. Другими словами, DOM можно использовать как объектную оболочку для управления любой структурой данных, которая может быть представлена с помощью XML.
В XML-модели данных многие объекты данных приложения определяются на XML. Так как XML имеет иерархическую структуру, легко понять взаимосвязь между объектами данных в естественном, удобном для чтения формате.
 |
Замечание:
Если ваши данные уже представлены в XML-формате, то оставшийся процесс будет естественным и очень простым. Даже если данные представлены в реляционном формате, вы все равно можете использовать предложенную методику, но потребуется взаимно однозначное преобразование реляционных данных в XML. Для этого можно использовать SQL/XML-функции публикации и нарезки. Большинство реляционных баз данных поддерживают эти функции наряду с другими технологиями преобразования. Для большинства разработчиков преобразование реляционных данных в иерархические (XML) только ради использования модели данных XML в разработке приложений может показаться ненужным. Но, будучи разработчиками, мы все время это делаем, когда преобразуем реляционные данные к объектным. Возможно, преимущества модели данных XML побудят многих разработчиков задуматься над использованием этой технологии в разработке приложений, даже если в бизнес-модели не нужны XML-данные. |
|
Когда модель данных XML определена, DOM-парсер может ее обработать в приложении. Чтобы изолировать код приложения от API DOM, который используется для навигации и управления XML-моделью, вы можете создать оболочку вокруг реализаций DOM и XPath. Эта оболочка также сделает ваш код более переносимым.
Я приложил к данной статье пример Java-оболочки. Вы можете использовать его как готовый вариант или как шаблон для своей собственной оболочки. Бизнес-логика приложения напрямую управляет моделью XML с помощью API-оболочки. Измененные XML-данные можно легко сериализовать и передавать между различными объектами или различными уровнями в многоуровневых средах (SOA).
Сравнение модели данных XML и объектной модели
Большинство приложений состоит из бизнес-объектов, управляемых иерархиями объектов данных. В общем случае объекты данных - это тонкие оболочки бизнес-данных. Их главная цель состоит в том, чтобы управлять представлением упакованных данных бизнес-объектам. Еще одно преимущество оболочек для объектов заключается в том, что они позволяют представлять данные, хранящиеся в реляционных таблицах, в естественной иерархии объектов, где можно зафиксировать взаимосвязь между данными. Большая часть усилий, затрачиваемых на написание кода, уходит на создание таких объектных оболочек для приложений с бизнес-данными.
Так как XML по своей сути поддерживает взаимосвязь структур данных, то не имеет смысла создавать отдельную иерархию объектов, чтобы зафиксировать взаимосвязь между отдельными структурами данных. Кроме того, у XML есть стандартная объектная модель – DOM (объектная модель документов). Реализации этой модели применяются для конструирования, изменения и сериализации XML-данных. Грамотное использование языка XPath совместно с программными интерфейсами DOM делает задачу загрузки, изменения и сохранения XML-данных в бизнес-приложениях тривиальной.
Наглядный пример
Чтобы лучше понять разницу этих двух моделей, давайте посмотрим, как каждая модель влияет на разработку и реализацию приложения.
На примерах кода я покажу два подхода, используя простой сценарий с заказчиком и информацией о заказе.
Объектная модель данных
В подходе с объектной моделью данных нам сначала надо создать оболочку объектов, чтобы инкапсулировать заказчика (customer) и данные заказа (order data), см. листинги 1, 2 и 3.
Листинг 1. Создание заказчика
public class Customer
{
int customerid;
String firstname;
String lastname;
Items itemspurchased ;
Public Customer (int custid, Connection conn)
{
Statement dbstmt= conn.createStatement();
ResultSet dbResult = dbstmt.executeQuery("select fname, lname from
customer_table where customerid=custid");
customerid=custid;
SetFirstName(dbResult.getString(1));
SetLastName(dbResult.getString(2));
}
public String GetFirstName {return firstname;}
public Void SetFirstName (fname) {firstname=fname;}
public String GetLastName {return lastname ;}
public Void SetLastName (lname) {lastname=lname;}
public Items GetItemsList {return itemspurchased; }
public SetItemsList (list) { itemspurchased =list;}
}
|
Листинг 2. Создание класса items (покупки)
public class Items
{
Hashtable list=new Hashtable();
Public Items(int custid,Connection conn)
{
Statement dbstmt= conn.createStatement();
ResultSet dbResult = dbstmt.executeQuery("select itemid, description,
price, date from purchase_table where customerid=custid")
While (dbResult.rs.next ())
{
tempitem = new Item();
tempitem.SetID(dbResult. getString(1));
tempitem. SetDescription (dbResult. getString(2));
tempitem. Setprice (dbResult. getFloat(3));
tempitem. SetpurchaseDate (dbResult. getString(4));
Additem (tempitem);
}
}
public void AddItem (item oneitem) {list.put(oneitem.GetID(),oneitem);}
public Item GetItem (ItemID) {return list.get(String itemID);}
public Hashtable GetItems(){return list;}
public Items FindItemByPrice (flaot min, float max)
{
Items retList=new Items();
for (Enumeration e=list.elements () ; e.hasMoreElements() ; )
{
item tmpItem=(item)e.nextElement();
float price= tmpItem .GetPrice();
if(price >= min && price <=max)
{
retList.AddItem(tmpItem);
}
}
}
public Items FindItemByDate (purchaseDate) { }
}
|
Листинг 3. Создание определения item (покупка)
public class Item
{
String id;
String description;
String purchaseDate;
Float price;
Public void SetID (String ItemID) {id= ItemID;}
Public void SetDescription (String desc) { description = desc;}
Public void SetpurchaseDate (String pDate) { purchaseDate = pDate ;}
Public void Setprice (float pprice { price = pprice ;}
Public String GetID (){return id;}
Public String GetDescription(){return description;}
Public float GetPrice(){return price;}
}
|
Этот объект данных можно использовать в приложении, чтобы управлять остальными данными.
Листинг 4. Управление объектами данных в приложении
Customer customer = new Customer (custid,dbConnection)
customer.SetItemList (new Items(custid , dbConnection)) ;
Items list=customer.GetItemsList(). FindItemByPrice(15.0,25.50);
for (Enumeration e=list.elements () ; e.hasMoreElements() ; )
{
System.out.println(((item)e.nextElement()).GetDescription());
}
|
Из представленных примеров мы видим, что код для объектов данных экспоненциально больше, чем код, описывающий бизнес-логику. Так как оболочка объектов скрывает взаимосвязи между заключенными в ней бизнес-данными, необходимо, чтобы API оболочки объекта были хорошо задокументированы, чтобы разработчики приложений понимали, как правильно их использовать.
Простое перемещение между иерархиями объектов встроено в объектную модель данных, но расширенные средства поиска и перемещения приходится реализовывать для каждого критерия поиска (например, FindItemByPrice) отдельно.
Модель данных XML
Поскольку главным мотивом к использованию оболочек объектов была инкапсуляция бизнес-данных, их можно заменить моделью данных XML.
Листинг 5. Модель данных XML
<Customer customerid ="" firstname="" lastname="" >
<Items>
<Item ID="" description="" purchaseDate="" price="" />
</Items>
</Customer>
|
Теперь, если данные в базе данных уже хранятся в формате XML следующим образом:
- данные покупателя (customer) в виде <Customer customerid ="" firstname="" lastname="" />
- данные покупки (item) в виде <Item ID="" description="" purchaseDate="" price="" />
- все, что нам надо сделать для любого заданного покупателя - это взять его XML и добавить его в список запрашиваемых покупок.
Давайте перепишем код приложения с использованием модели XML для хранения информации о покупателе и покупках. Чтобы создать экземпляр этой модели данных XML и управлять им, мы будем использовать класс DOM-оболочки XMLParser. Его можно загрузить в разделе Загрузка.
Первый случай - Данные хранятся в базе данных в формате XML
Листинг 6. Переписывание приложения с использованием модели XML
1. Statement dbstmt= conn.createStatement();
2. ResultSet dbResult = dbstmt.executeQuery("select custXML from
customer_table where customerid=custid");
3. XMLParse customerXML = new XMLParse(dbResult. getString(1));
4. customerXML.appendNode("/Customer", customerXML.createNode ("<Items/>"))
5. dbResult = dbstmt.executeQuery("select itemXML from purchase_table
where customerid=custid");
6. While (dbResult.rs.next ()) {
7. Node itemnode= customerXML.createNode (dbResult. getString(1));
8. customerXML.appendNode(itemnode ,"/Customer/Items",false);
}
9. customerXML.find("/Customer/Items/item[@price>15.0 and @price <25.5]",true);
10. for(int i=0;i < customerXML.currentFind.getLength();i++) {
11. System.out.println(customerXML.getValue("@description",i));
}
|
Первый запрос (вторая строка) возвращает XML-данные в столбце custXML для заданного покупателя. Эта XML-строка посылается в конструктор DOM-оболочки (третья строка), который, в свою очередь, с помощью XML-парсера обрабатывает иерархию объектов, представленную XML-данными.
Замечание:
Так как у покупателя (customerXML) нет ни одной покупки, т.е. ни одного элемента Items (потому что мы так определили в XML- схеме для нашей модели), мы создаем новый элемент Items (четвертая строка) и присоединяем его как дочерний элемент к Customer.
Результат второго запроса (пятая строка) возвращает из базы данных список покупок, приобретенных покупателем (в XML-формате). Каждая покупка в списке (седьмая строка) прикрепляется (восьмая строка) к иерархии объектов в DOM с путем Customer/items.
Наконец, с помощью XPath мы ищем все покупки в заданной ценовой категории (девятая строка) в иерархии объектов DOM и выводим описание каждой найденной покупки (десятая строка).
Второй случай - Все данные хранятся в реляционной базе данных
Так как данные хранятся не в XML-формате, нам надо будет сделать внутри запроса преобразование с использованием SQL/XML-функций публикации.
Листинг 7. Преобразование с использованием SQL/XML-функций публикации
1. Statement dbstmt= conn.createStatement();
2. ResultSet dbResult = dbstmt.executeQuery("select xmlelement( name \"Customer\" ,
xmlattributes(customerid as \"customerid\" ),
xmlattributes(fname as \"firstname\" ),
xmlattributes(lname as \"lastname\" )
) from customer_table where customerid=custid");
3. XMLParse customerXML = new XMLParse(dbResult. getString(1));
5. dbResult = dbstmt.executeQuery("select xmlelement( name \"items\" ,
xmlelement( name \"item\" ,
xmlattributes(itemid as \"id\" ),
xmlattributes(description as \"description\" ),
xmlattributes(price as \"price\" ),
xmlattributes(date as \"purchaseDate\" )
)
) from purchase_table where customerid=custid");
6. if (dbResult.rs.next ()) {
7. Node itemsnode= customerXML.createNode (dbResult. getString(1));
8. customerXML.appendNode(itemsnode ,"/Customer",false);
}
9. customerXML.find("/Customer/Items/item[@price>15.0 and @price <25.5]",true);
10. for(int i=0;i < customerXML.currentFind.getLength();i++) {
11. System.out.println(customerXML.getValue("@description",i));
}
|
Несмотря на то, что в нашей базе не было XML, мы с помощью SQL создали XML-представление реляционных данных для нашего приложения. Также мы добавили внешний элемент items, одновременно создавая XML-элемент items в запросе. Все, что нам осталось сделать - это добавить покупку в формате XML к покупателю в том же формате. Оставшаяся часть приложения остается без изменений.
Преимущества использования модели XML перед "чистой" объектной моделью
Оболочки объекта данных занимают большую часть кода приложения, фактически отвлекая внимание от бизнес-логики для управления объектами данных. Кроме того, этот дополнительный код влечет:
-
дополнительные траты;
-
больше ошибок;
-
более длинный цикл разработки приложения;
-
менее гибкий и переносимый код;
-
необходимость изменять или заново создавать иерархию объектов каждый раз, когда возникают изменения в схеме данных;
- сложность поддержки кода;
-
отсутствие встроенной проверки данных;
- больший объем документации для объяснения оболочки объектов;
- более сложную логику реализации для осуществления таких возможностей, как расширенные поиск и навигация по иерархии объектов;
- необходимость обработки сериализации данных для каждого бизнес-объекта;
- привязку приложения к инструментарию, применяемому для преобразования (если таковой используется);
Используя методологии XML-программирования, можно исключить всю иерархию объектов с оболочкой, позволив программистам уделить больше внимания бизнес-логики, а не структуре бизнес-данных. XML дает следующие преимущества при программировании:
-
уменьшает объем кода, что приводит к лучшему качеству, более низким затратам и большей гибкости;
-
содействует RAD-разработке;
-
усовершенствованные возможности поиска и навигации уже встроены в XPath-парсер;
-
в XML-модели уже встроены проверки ограничений и проверка по схеме;
-
модель обладает свойством персистентности. В любой момент вы можете перевести иерархию XML-данных в файл, строку или поток;
-
не нужны дополнительные инструменты;
-
эта методология открывает взаимосвязи и иерархию данных для бизнес-логики. Из кода бизнес-объектов сложно понять формат структуры бизнес-данных, которыми вы управляете (т.е. модель данных скрыта от бизнес-кода). В реляционном мире это необходимость, в мире XML это может оказаться недостатком;
-
код бизнес-логики легко читать, потому что XPath описывает точную природу данных и их взаимосвязи с бизнес-структурой.
Проблемы и решения при адаптации к XML-модели
Если реляционные данные не хранятся в XML, то их необходимо преобразовать в этот формат. Процесс преобразования является громоздким, несмотря на то, что многие поставщики позаботились о необходимом инструментарии. Однако с введением поддержки "чистого" XML в такие серверы баз данных, как DB2 и Microsoft® SQL Server, отпала необходимость в преобразовании и нарезке XML-данных для хранения в реляционных таблицах. Данные, которые хранятся в XML, с помощью и XQuery и XML-индексов можно находить и возвращать в целости в приложение таким же образом, как вы могли бы вернуть из базы данных большой символьный объект.
Если данные хранятся в базе данных как чистый XML, для создания XML-запросов надо понимать назначение функций SQL/XML и xQuery. Чтобы уменьшить затраты на переход на XML-запросы, начните с простого XPath вместо сложных запросов XQuery.
Процесс изучения и профессионального освоения интерфейсов DOM и их реализаций, а также навигации и поиска в иерархии XML с использованием XPath может оказаться сложной задачей. Используйте вспомогательный класс (helper class), прикрепленный к данной статье, чтобы уменьшить необходимость напрямую вызывать интерфейсы DOM. Этот вспомогательный класс обволакивает интерфейсы DOM и представляет более естественные API, чем содержащиеся в коде. Он обладает необходимой функциональностью для обработки и сериализации XML-модели и для поиска и изменения данных или метаданных в экземпляре XML. Этот класс-оболочка также реализует XSL-преобразования, пространства имен и проверку на соответствие схеме, если это необходимо.
Прямое встраивание вызовов DOM API в бизнес-логику приложения нерационально, так как любое изменение в XML-схеме требует больших изменений в коде приложения. Многие вызовы API используются для перемещения по иерархии, и это снижает читаемость кода. Данные объекта, по которому осуществляются навигация и поиск, не такие явные, как в оболочке объекта, определенной пользователем. Наш класс-оболочка исключает необходимость встраивать вызовы DOM API в бизнес-логику. Поскольку класс-оболочка перемещается по DOM с помощью XPath, любые изменения в схеме, влияющие на код приложения, требуют изменения только в строках XPath API-вызовов оболочки из приложения. Благодаря тому, что XPath показывает место положения рассматриваемого узла в иерархии XML, читаемость кода приложения оказывается очень высокой.
Заключение
Прямое встраивание вызовов DOM API в бизнес-логику приложения нерационально, так как любое изменение в XML-схеме требует больших изменений в коде приложения. Многие вызовы API используются для перемещения по иерархии, и это снижает читаемость кода. Данные объекта, по которому осуществляются навигация и поиск, не такие явные, как в оболочке объекта, определенной пользователем. Наш класс-оболочка исключает необходимость встраивать вызовы DOM API в бизнес-логику. Поскольку класс-оболочка перемещается по DOM с помощью XPath, любые изменения в схеме, влияющие на код приложения, требуют изменения только в строках XPath API-вызовов оболочки из приложения. Благодаря тому, что XPath показывает место положения рассматриваемого узла в иерархии XML, читаемость кода приложения оказывается очень высокой.
Применяя модель данных XML, можно исключить всю иерархию объектных оболочек данных, чтобы программисты могли сосредоточиться на бизнес-логике, а не на управлении бизнес-данными. С помощью класса-оболочки DOM код приложения изолируется от интерфейса DOM. Применение XPath для навигации делает код приложения понятнее, поскольку отображает связи с рассматриваемыми бизнес-данными.
В идеале данные должны храниться в базе данных как чистый XML, но даже если данные находятся в реляционных таблицах, все равно во многих случаях стоит сразу преобразовать их в XML, чтобы затем работать с ними в приложении.
Если структуры данных, упакованных внутри иерархии объектов, могут быть преобразованы с использованием XML, и если главной целью иерархии объектов является управление и отображение структур этих данных в бизнес-логику, то иерархию объектных оболочек данных можно заменить моделью DOM.
Во второй части данной серии вы научитесь адаптировать архитектуру XML-приложений к своим приложениям в DB2.
Загрузка | Описание | Имя | Размер | Метод загрузки |
|---|
| Классы-оболочки DOM и XPath для java | XMLParse.java | 30KB | HTTP |
|---|
Ресурсы Научиться
- Оригинал статьи "Programming with XML for DB2, Part 1: Understand the XML data model" (EN).
- Страница технологии
DB2 pureXML™
: узнайте больше о поддержки XML в DB2.
-
Успех ISV с DB2 Viper (ISV success with DB2 Viper) (EN) (developerWorks, март 2006 г.): узнайте о наиболее значимых для независимых поставщиков ПО (ISV) изменениях в продуктах DB2 9 и о том, как они могут повлиять на скрипты и код приложения существующих баз данных.
-
Запуск гибридного механизма (Firing Up The Hybrid Engine) (EN) (Журнал DB2, июль 2005 г.): изучите встроенную поддержку XML в DB2. (EN)
-
Что нового в DB2 Viper (What's new in DB2 Viper) (developerworks, февраль 2006 г.): узнайте, в каких наиболее важных направлениях DB2 9 отличается от предыдущих версий.
-
Быстрый и успешный старт в DB2 Viper (Get off to a fast start with DB2 Viper) (EN) (developerWorks, март 2006 г.): начните с улучшения возможностей XML в DB2 9.
-
DB2 и XML: Запрос XML-данных при помощи SQL (Query DB2 XML data with SQL) (developerWorks, март 2006 г.): изучите основы запросов данных в DB2 с помощью SQL.
-
Запрос XML-данных при помощи языка XQuery (Query DB2 XML data with XQuery) (developerWorks, апрель 2006 г.): изучите основы запросов данных в DB2 с помощью XQuery.
-
От схемы DAD к декомпозиции аннотируемой XML-схемы (From DAD to annotated XML schema decomposition) (developerWorks, апрель 2006 г.): приступая к декомпозиции XML-схемы.
-
Преобразование по умолчанию аннотируемой XML-схемы (Default mapping for annotated XML schema) (EN) (developerWorks, апрель 2006 г.): узнайте основы декомпозиции аннотируемой XML-схемы.
-
Совместное использование встроенной поддержки XML в DB2 и PHP (Use DB2 native XML with PHP) (developerWorks, ноябрь 2005): статья является введением в основные понятия pureXML.
-
Встроенная поддержка XML в универсальной базе данных DB2 (Native XML support in DB2 Universal Database) (EN): сравните новую поддержку XML в DB2 с традиционной реляционной технологией баз данных.
-
Рекомендации W3C по расширенному языку разметки (XML): на этом сайте приведена информация о происхождении и целях XML. (EN)
- Посетите страницу ресурсов developerWorks по технологиям DB2 для Linux, UNIX и Windows, чтобы почитать статьи и руководства, а также найти другие ресурсы для расширения своих навыков в DB2.(EN)
-
Ознакомьтесь с версией DB2 Express-C - бесплатной версией DB2 Express Edition для сообщества разработчиков.(EN)
Получить продукты и технологии
- Загрузите бесплатную пробную версию DB2 Enterprise 9.(EN)
- Теперь вы можете пользоваться DB2 бесплатно. Загрузите DB2 Express-C - бесплатную версию DB2 Express Edition для сообщества разработчиков, которая предоставляет те же основные возможности, что и DB2 Express Edtion, и предоставляет надежную основу для построения и развертывания приложений.(EN)
Обсудить
Об авторе  | |  | Хардип Сингх (Hardeep Singh) – член группы встроенной поддержки XML в DB2. Он является разработчиком инструментария DB2 XML и отвечает за миграцию приложений XML Extender на версию Viper. Его опыт работы в промышленности насчитывает 21 год. |
Выскажите мнение об этой странице
|  |