Примеры
создания приложений баз данных
В Kylix нет стандартных
компонентов для создания многих локальных баз данных. Связано это с тем, что
такие форматы данных являются отмирающими, тем более что преобразование их в
формат XML не вызывает больших затруднений.
Базы данных типа MyBase
предоставляют программисту дополнительные возможности.
Для иллюстрации всего вышесказанного
создадим приложение просмотра и редактирования заказов.
Начнем с создания заготовки
приложения. В главном меню Kylix выберем пункт File/New Application (рис.
18.1).
При этом среда создаст
проект с пустой формой Form1. Добавим модуль данных. Для этого выберем
в главном меню Kylix пункт File/New и в открывшемся диалоговом окне выберем
пиктограмму Data Module (рис. 18.2).
Теперь в модуль данных
поместим компонент ClientDataSet с вкладки 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. Определения полей
|
Имя поля |
Описание |
Тип данных |
Размер |
|
|
счетчик |
|
0 |
|
|
имя клиента |
|
50 |
Рис.
18.5. Установка свойств поля ID в окне Object Inspector
Рис.
18.6. Установка свойств поля Name в окне Object Inspector
Рис.
18.7. Поля ID и Name
Правой кнопкой мыши щелкнем
на компоненте Clients и выберем в выпадающем меню пункт 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 установим равным Сlients). Затем установим
свойство 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="Autoxnc"
/>
<FIELD
attrname="Name" fieldtype="string" WIDTH="50"
/>
</FIELDS>
<PARAMS
DEFAULT_ORDER="" AUTOINCVALUE="1" />
</
METADATA>
<ROWDATA
/>
</DATAPACKET>
В первой строке содержится
заголовок:
<?xml version
= "1.0" encoding="UTF-8" standalone="yes" ?>
Вторая строка содержит корневой
тэг документа:
<DATAPACKET Version="2.0">
Всю остальную часть файла
можно разделить на две части:
Метаданные хранятся в тэге
METADATA, а записи — в тэге ROW DATA. После создания
новой таблицы базы данных тэг ROWDATA будет пустым.
Внутри тэга METADATA
расположены описания полей таблицы (тэг FIELDS и вложенные в него
тэги) и другая служебная информация (порядок сортировки
по умолчанию, начальное значение автоматически увеличивающегося счетчика).
Теперь давайте запустим
наше приложение, вставим в таблицу новую запись, закроем приложение и посмотрим,
как изменился xml-файл.
Мы видим, что изменился
тэг PARAMS:
<PARAMS CHANGE_LOG="1
0 4" AUTOINCVALUE="2" DEFAULT_ORDER="" />
Кроме того, тэг ROWDATA
тоже изменился:
<ROWDATA>
<ROW
RowState="4" ID="1" Name="e?AI?"
/>
</ROWDATA>
Если вы внимательно посмотрите
на изменения, то увидите, что внутри таблицы ведется журнал операций. Это дает
возможность сделать отмену произведенных действий.
Если вам не нужно, чтобы
этот журнал велся, в режиме выполнения программы установите свойство LogChanges
в false.
Рассмотрим установку отношений
таблиц "главный-подчиненный" (master-detail).
Новым способом организации
отношения master-detail в Kylix стало использование вложенных наборов данных.
Предположим, что нам нужно получить информацию о покупках, сделанных клиентом.
Сначала очистим набор данных
Сlients. Для этого щелкнем правой кнопкой мыши на компоненте Сlients
и в выпадающем меню выберем пункт очистки данных Clear Data.
Введем дополнительное описание
полей Оrders типа ftDataSet. Данный тип поля предназначен
для хранения внутри себя наборов данных. Список полей вложенного набора данных
устанавливается в свойстве ChildDefs. Определим в ChildDefs
следующие поля (табл. 18.2).
Таблица
18.2. Поля, определяемые в свойстве ChlidDefs
|
Имя поля |
Описание |
Тип данных |
Размер |
|
|
счетчик |
|
0 |
|
|
описание заказа |
|
20 |
|
|
цена заказа |
|
0 |
Осталось только на основе
описанных определений создать набор данных (щелкнув правой кнопкой мыши и выбрав
пункт выпадающего меню Create Data Set). Затем сохранить в файл (Save
to MyBase xml table) и на основе этих определений явным образом создать
поля (дважды щелкнув на Clients,
затем щелнув правой кнопкой мыши и выбрав пункт Add all fields). Откроем
созданный xml-файл (листинг 18.2).
Листинг 18.2. Содержимое
файла базы данных
<?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"
/>
- <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_ORDER="" AUTOINCVALUE="1" />
</METADATA>
<ROWDATA
/>
</DATAPACKET>
Нетрудно убедиться в том,
что поле Оrders содержит в себе описание подчиненной таблицы. При
этом в сетке данных DBGrid1, расположенной на главной форме, появился
новый столбец Оrders. При запуске приложения и попытке редактирования
этого поля автоматически открывается форма для редактирования вложенного набора
данных.
Другим способом организации
взаимодействия с вложенным набором данных является размещение в модуле данных
дополнительного клиентского набора данных ClientDataSet. Поместим
в модуль данных еще один компонент типа TClientDataSet, установив
его имя orders. Свойству DataSetField компонента Orders
из раскрывающегося списка присвоим значение ClientsOrders. Теперь,
пользуясь компонентом Оrders, можно просматривать и редактировать
вложенный набор данных.
Достоинства вышеописанного
метода в том, что вся база будет храниться в одном xml-файле, недостаток — в
том, что нельзя разорвать связь главный-подчиненный и, как следствие, одновременно
посмотреть все записи о заказах вне зависимости от выбранного клиента.