Сапа
Здесь может быть ваша реклама
|

 Глава 18. Примеры создания приложений баз данных

Глава 18. Примеры создания приложений баз данных

В Kylix нет стандартных компонентов для создания многих локальных баз данных. Связано это с тем, что такие форматы данных являются отмирающими, тем более что преобразование их в формат XML не вызывает больших затруднений.
Базы данных типа MyBase предоставляют программисту дополнительные возможности.
- Сортировка данных по полям без создания дополнительных файлов индексов.
- Ведение списка изменений и отката сделанных изменений.
- Создание агрегатов на основе данных таблицы.
- Совместное использование одних и тех же данных несколькими наборами данных.
- Совместимость с Delphi 5 и Delphi 6.
Для иллюстрации всего вышесказанного создадим приложение просмотра и редактирования заказов.
Начнем с создания заготовки приложения. В главном меню Kylix выберем пункт File/New Application (рис. 18.1).
При этом среда создаст проект с пустой формой Forml. Добавим модуль данных. Для этого выберем в главном меню Kylix пункт File/New и в открывшемся диалоговом окне выберем пиктограмму Data Module (рис. 18.2).
Теперь в модуль данных поместим компонент ciientoataSet с вкладки DataAccess. Установим свойство Name данного компонента в компонент clients. Этот набор данных будет хранить информацию о заказчиках (рис. 18.3).
Для создания файла базы данных необходимо указать поля и их типы. Сделать это можно двумя способами:
- определить значение свойства FieldDefs клиентского набора данных;
- создать объекты полей явным образом.

Рис. 18.1. Окно New Items

Рис. 18.2. Пиктограмма Data Module окна New Items



Рис. 18.3. Компонент Clients в окне модуля данных

Создадим поля первым способом. Для этого дважды щелкнем на свойства FieldDefs компонента Clients. При этом откроется диалоговое окно добавления новых полей (рис. 18.4).

Рис. 18.4. Диалоговое окно добавления новых полей

Добавим определения полей, представленные в табл. 18.1.

Таблица 18.1. Определения полей

Имя поляОписаниеТип данныхРазмер
IDсчетчикftAutoInc0
Nameимя клиентаFtString50

Рис. 18.5. Установка свойств поля ID в окне Object Inspector

Рис. 18.6. Установка свойств поля в окне Object Inspector

Рис. 18.7. Поля ID и Name

Правой кнопкой мыши щелкнем на компоненте Сlients и выберем в выпадающем меню пункт CreateDataSet, а затем - пункт Save To MyBase Xml UTF-8 table. В появившемся диалоговом окне укажем имя xml-файла, который будет хранить данные о клиентах - Clients.xml и являться главной таблицей нашей базы данных (рис. 18.8).
Для того чтобы при запуске программы клиентский набор данных Clients читал данные из созданного нами xml-файла, значение его свойства Filename должно быть равно полному имени xml-файла.

 

 

 

 

Рис. 18.8. Диалоговое окно сохранения файла таблицы

Теперь определим поля явно на основе FieldDefs. Дважды щелкнем на компоненте Clients, в появившемся диалоговом окне щелчком правой кнопкой мыши откроем контекстное меню и выберем пункт добавления всех полей Add all fields (рис. 18.9).

Рис. 18.9. Поля компонента Clients

Разместим в модуле данных компонент DataSource, установим его свойство Name в ds_Clients и свяжем его с компонентом Clients (свойство DataSet компонента ds_Clients установим равным Clients). Затем установим свойство DataSource в ds_Clients. Окончательный вид модуля данных показан на рис. 18.10.Посмотрим, как устроен внутри файл базы данных xml. После создания набора данных типичный файл базы данных выглядит, как представлено в листинге 18.1.

Рис. 18.10. Модуль данных

Листинг18.1 Содержание типичного файла базы данных
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<DATAPACKET Version="2.0">
<METADATA>
<FIELDS>
<FIELD attrname="ID" fieldtype="i4" readonly="true" SUBTYPE="Autoinc"/>
<FIELD attrname="Name" fieldtype="string" WIDTH="50" />
</FIELDS>
<PARAMS DEFAULT_ORDER="" AUTOINCVALUE="1" />
</METADATA>
<ROWDATA />
</DATAPACKET>

В первой строке содержится заголовок:
<?xml version="l . О" encoding="UTF-8" standalone="yes" ?>
Вторая строка содержит корневой тэг документа:
<DATAPACKET Version="2.0">
остальную часть файла можно разделить на две части:
- данные о структуре таблицы базы данных, хранимые в файле (метаданные);
- непосредственно записи.
Метаданные хранятся в тэге METADATA, а записи - в тэге ROWDATA. После создания новой таблицы базы данных тэг ROWDATA будет пустым.
Внутри тэга METADATA расположены описания полей таблицы (тэг FIELDS и вложенные в него тэги) и другая служебная информация (порядок сортировки по умолчанию, начальное значение автоматически увеличивающегося счетчика).
Теперь давайте запустим наше приложение, вставим в таблицу новую запись, закроем приложение и посмотрим, как изменился xml-файл.
Мы видим, что изменился тэг PARAMS:

<PARAMS CHAGE_LOG="1 0 4" AUTOINCVALUE="2" DEFAULT_ORDER>

Кроме того, тэг ROWDATA тоже изменился:

<ROWDATA>
<ROW RowStace="4" ID="1" Name="e?AI?" />
</ROWDATA>

Если вы внимательно посмотрите на изменения, то увидите, что внутри таблицы ведется журнал операций. Это дает возможность сделать отмену произведенных действий.
Если вам не нужно, чтобы этот журнал велся, в режиме выполнения программы установите свойство LogChanges в false.
Рассмотрим установку отношений таблиц "главный-подчиненный" (master-detail).
Новым способом организации отношения master-detail в Kylix стало использование вложенных наборов данных. Предположим, что нам нужно получить информацию о покупках, сделанных клиентом.
Сначала очистим набор данных Clients. Для этого щелкнем правой кнопкой мыши на компоненте Clients и в выпадающем меню выберем пункт очистки данных Clear Data.
Введем дополнительное описание полей Orders типа ftDataSet. Данный тип поля предназначен для хранения внутри себя наборов данных. Список полей вложенного набора данных устанавливается в свойстве ChildDef; Определим в ChildDefs следующие поля (табл. 18.2).

Таблица 18.2. Поля, определяемые в свойстве ChildDefs

Имя поляОписаниеТип данныхРазмер
IDсчетчикFtAutoInc0
OrderNameописание заказаFtString20
Priceцена заказаFtCurrency0

Осталось только на основе описанных определений создать набор данных (щелкнув правой кнопкой мыши и выбрав пункт выпадающего меню Create DataSet). Затем сохранить в файл (Save to MyBase xml table) и на основе этих определений явным образом создать поля (дважды щелкнув на Clients, затем шелнув правой кнопкой мыши и выбрав пункт Add all fields). Откроем созданный xml-файл (листинг 18.2).

Листинг 18.2. Содержимое файла базы данных
<?xml version=" 1.0" encodinq = "UTF-8" standalone ="yes"?>
- <DATAPACKET Version="2.0">
- <METADATA>
- <FIELDS>
<FIELD attrname="ID" f ieldtype="i4" readonly="true" SUBTYPE="Autoinc"/>
<FIELD attrname="Name" fieldtype="string" WIDTH="50" />
- <FIELD attrname="0rders" fieldtype="nested">
- <FIELDS>
<FIELD attrname="ID" fieldtype="i4" SUBTYPE="Autoinc" />
<FIELD attrname="OrderName" fieldtype="string" WIDTH="20"
<FIELD attrname="Price" fieldtype="r8" SUBTYPE="Money" />
</FIELDS>
<PARAMS AUTOINCVALUE="1" />
</FIELD>
</FIELDS>
<PARAMS DEFAULT OROER^"" AUTOINCVALUE="1" />
</METADATA>
<ROWDATA />
</DATAPACKET>

Нетрудно убедиться в том, что поле Orders содержит в себе описание подчиненной таблицы. При этом в сетке данных DBGridi, расположенной на главной форме, появился новый столбец Orders. При запуске приложения и "попытке редактирования этого поля автоматически открывается форма для редактирования вложенного набора данных.
Другим способом организации взаимодействия с вложенным набором данных является размещение в модуле данных дополнительного клиентского набора данных ClientDataSet. Поместим в модуль данных еще один компонент типа TdientDataSet, установив его имя Orders. Свойству SetField компонента Orders из раскрывающегося списка присвоим значение ClientsOrders. Теперь, пользуясь компонентом Orders, можно просматривать и редактировать вложенный набор данных.
Достоинства вышеописанного метода в том, что вся база будет храниться в одном xml-файле, недостаток - в том, что нельзя разорвать связь главный-подчиненный и, как следствие, одновременно посмотреть все записи о заказах вне зависимости от выбранного клиента.

 
MKPortal©2003-2008 mkportal.it
MultiBoard ©2007-2009 RusMKPortal