Архитектура приложений баз данных


Приложение баз данных, как следует уже из его названия, предназначено для взаимодействия с некоторым источником данных — базой данных (БД). Взаимодействие подразумевает получение данных, их представление в определенном формате для просмотра пользователем, редактирование в соответствии с реализованными в программе бизнес- алгоритмами и возврат обработанных данных обратно в базу данных.
В качестве источника данных могут выступать как собственно базы данных, так и обычные файлы — текстовые, электронные таблицы и т. д. Но здесь мы будем рассматривать приложения, работающие с базами данных.
Как известно, базы данных обслуживаются специальными программами — системами управления базами данных (СУБД), которые делятся на локальные, преимущественно однопользовательские, предназначенные для настольных приложений, и серверные — сетевые (часто удаленные), многопользовательские, функционирующие на выделенных компьютерах — серверах. Главный критерий такой классификации — объем базы данных и средняя нагрузка на СУБД.
Тем не менее, несмотря на разнообразие реализаций, общая архитектура приложения баз данных остается неизменной.
Само приложение включает механизм получения и отправки данных, механизм внутреннего представления данных в том или ином виде, пользовательский интерфейс для отображения и редактирования данных, бизнес-логику для обработки данных.
Механизм получения и отправки данных обеспечивает соединение с источником данных (часто опосредованно). Он должен "знать", куда ему обращаться и какой протокол обмена использовать для обеспечения двунаправленного потока данных.
Механизм внутреннего представления данных является ядром приложения баз данных. Он обеспечивает хранение полученных данных в приложении и предоставляет их по запросу других частей приложения.
Пользовательский интерфейс обеспечивает просмотр и редактирование данных, а также управление данными и приложением в целом.
Бизнес-логика приложения представляет собой набор реализованных в программе алгоритмов обработки данных.
Между приложением и собственно базой данных находится специальное программное обеспечение (ПО), связывающее программу и источник данных и управляющее процессом обмена данными. Это ПО может быть реализовано самыми разнообразными способами, в зависимости от объема базы данных, решаемых системой задач, числа пользователей, способами соединения приложения и базы данных. Промежуточное ПО может быть реализовано как окружение приложения, без которого оно вообще не будет работать, как набор драйверов и динамических библиотек, к которым обращается приложение, может быть интегрировано в само приложение. Наконец, это может быть отдельный удаленный сервер, обслуживающий тысячи приложений.
Источник данных представляет собой хранилище данных (саму базу данных) и СУБД, управляющую данными, обеспечивающую целостность и непротиворечивость данных.
В этой и последующих главах части III мы подробно остановимся на способах разработки приложений баз данных в Delphi. При разнообразии способов реализации и обилии технических деталей общая архитектура приложений баз данных в Delphi следует описанной выше общей схеме.
В Delphi 7 реализовано достаточно большое число разнообразных технологий доступа к данным (они рассматриваются далее в этой книге). Но последовательность операций при конструировании приложений баз данных остается почти одинаковой. И в работе используются по сути одни и те же компоненты, доработанные для применения с той или иной технологией доступа к данным.
В этой главе рассматриваются общие подходы к разработке приложений баз данных в Delphi, базовые классы и механизмы, которые не изменятся, выберите ли вы для вашего приложения Borland Database Engine (BDE), Microsoft ActiveX Data Objects (ADO) или dbExpress.
 Примечание
Главы части IV построены на основе материала глав этой части. Излагаемые здесь сведения являются базовыми для понимания процесса разработки и функционирования приложений баз данных в Delphi. Поэтому в последующем материале столь часто встречаются ссылки на главы этой части.
Итак, в этой главе рассматриваются следующие вопросы:

  • структура приложения баз данных в Delphi;
  •  базовые компоненты, используемые при разработке приложений баз данных, и их взаимосвязь;
  •  понятие набора данных и его участие в основных механизмах приложения баз данных;
  •  модуль данных;
  •  программная реализация частей приложения баз данных.

Как работает приложение баз данных


В Репозитории Delphi отсутствует отдельный шаблон для приложения баз данных. Поэтому, как и любое другое приложение Delphi, приложение баз данных начинается с обычной формы. Безусловно, это оправданный подход, т. к. приложение баз данных имеет пользовательский интерфейс. И этот интерфейс создается с использованием стандартных и специализированных визуальных компонентов на обычных формах.
Визуальные компоненты отображения данных расположены на странице Data Controls Палитры компонентов. В большинстве они представляют собой модификации стандартных элементов управления, приспособленных для работы с набором данных (см. гл. 15).
Приложение может содержать произвольное число форм и использовать любой интерфейс (MDI или SDI). Обычно одна форма отвечает за выполнение группы однородных операций, объединенных общим назначением.
В основе любого приложения баз данных лежат наборы данных, которые представляют собой группы записей (их удобно представить в виде таблиц в памяти), переданных из базы данных в приложение для просмотра и редактирования. Каждый набор данных инкапсулирован в специальном компоненте доступа к данным. В VCL Delphi реализован набор базовых классов, поддерживающих функциональность наборов данных, и практически идентичные по составу наборы дочерних компонентов для технологий доступа к данным. Их общий предок — класс TDataSet. (Подробно наборы данных рассмотрены в гл. 12.)
Для обеспечения связи набора данных с визуальными компонентами отображения данных используется специальный компонент TDataSource. Его роль заключается в управлении потоками данных между набором данных и связанными с ним компонентами отображения данных. Этот компонент обеспечивает передачу данных в визуальные компоненты и возврат результатов редактирования в набор данных, отвечает за изменение состояния визуальных компонентов при изменении состояния набора данных, передает сигналы управления от пользователя (визуальных компонентов) в набор данных. Компонент TDataSource расположен на странице Data Access Палитры компонентов.
Таким образом, базовый механизм доступа к данным создается триадой компонентов:

  •  компоненты, инкапсулирующие набор данных (потомки класса TDataSet);
  •   компоненты TDataSource;
  •  визуальные компоненты отображения данных.

Рассмотрим схему взаимодействия этих компонентов в приложении баз данных (1).
В приложении с источником данных или промежуточным программным обеспечением взаимодействует компонент доступа к данным, который инкапсулирует набор данных и обращается к функциям соответствующей технологии доступа к данным для выполнения различных операций. Компонент доступа к данным представляет собой "образ" таблицы базы данных в приложении. Общее число таких компонентов в приложении не ограничено.
С каждым компонентом доступа к данным может быть связан как минимум один компонент TDataSource. В его обязанности входит соединение набора данных с визуальными компонентами отображения данных. Компонент TDataSource обеспечивает передачу в эти компоненты текущих значений полей из набора данных и возврат в него сделанных изменений.
Еще одна функция компонента TDataSource заключается в синхронизации поведения компонентов отображения данных с состоянием набора данных. Например, если набор данных не активен, то компонент TDataSource обеспечивает удаление данных из компонентов отображения данных и их перевод в неактивное состояние. Или, если набор данных работает в режиме "только для чтения", то компонент TDataSource обязан передать в компоненты отображения данных запрещение на изменение данных.
С одним компонентом TDataSource могут быть связаны несколько визуальных компонентов отображения данных. Эти компоненты представляют собой модифицированные элементы управления, которые предназначены для показа информации из наборов данных.
При открытии набора данных компонент обеспечивает передачу в набор данных записей из требуемой таблицы БД. Курсор набора данных устанавливается на первую запись. Компонент TDataSource организует передачу в компоненты отображения данных значений необходимых полей из текущей записи. При перемещении по записям набора данных текущие значения полей в компонентах отображения данных автоматически обновляются.
Пользователь при помощи компонентов отображения данных может просматривать и редактировать данные. Измененные значения сразу же передаются из элемента управления в набор данных при помощи компонента TDataSource. Затем изменения могут быть переданы в базу данных или отменены.
Теперь, имея общее представление о работе приложения баз данных, перейдем к поэтапному рассмотрению процесса создания такого приложения.
 
Модуль данных
Для размещения компонентов доступа к данным в приложении баз данных желательно использовать специальную "форму" — модуль данных (класс TDataModule). Обратите внимание, что модуль данных не имеет ничего общего с обычной формой приложения, ведь его непосредственным предком является класс TComponent. В модуле данных можно размещать только невизуальные компоненты. Модуль данных доступен разработчику, как и любой другой модуль проекта, на этапе разработки. Пользователь приложения не может увидеть модуль данных во время выполнения.
Для создания модуля данных можно воспользоваться Репозиторием объектов или главным меню Delphi. Значок модуля данных Data Module расположен на странице New.
Как уже говорилось, модуль данных имеет мало общего со стандартной формой, хотя бы потому, что класс TDataModule происходит непосредственно от класса TComponent. У него почти полностью отсутствуют свойства и методы-обработчики событий, ведь от платформы для других невизуальных компонентов почти ничего не требуется, хотя потомки модуля данных, работающие в распределенных приложениях, выполняют весьма важную работу.
Для создания структуры (модели, диаграммы) данных, с которой работает приложение, можно воспользоваться возможностями, предоставляемыми страницей Diagram Редактора кода. Любой элемент из иерархического дерева компонентов модуля данных можно перенести на страницу диаграммы и задать связи между ними.
При помощи управляющих кнопок можно задавать между элементами диаграммы отношения синхронного просмотра и главный/подчиненный. При этом производится автоматическая настройка свойств соответствующих компонентов.
Для создания модуля данных (2) можно воспользоваться Репозиторием объектов или главным меню Delphi. Значок модуля данных Data Module расположен на странице New.
Для обращения компонентов доступа к данным, расположенным в модуле данных, из других модулей проекта необходимо включить имя модуля в секцию uses:
unit InterfaceModule;
...
 implementation
uses DataModule; 
...
DataModule.Tablel.Open;
...
Преимуществом размещения компонентов доступа к данным в модуле данных является то, что изменение значения любого свойства проявится сразу же во всех обычных модулях, к которым подключен этот модуль данных. Кроме этого, все обработчики событий этих компонентов, т. е. вся логика работы с данными приложения, собраны в одном месте, что тоже весьма удобно.
Подключение набора данных
Компонент доступа к данным является основой приложения баз данных. На основе выбранной таблицы БД он создает набор данных и позволяет эффективно управлять им. В процессе работы такой компонент тесно взаимодействует с функциями соответствующей технологии доступа к данным. Обычно доступ к функциональности технологии доступа к данным осуществляется через совокупность интерфейсов. Все компоненты доступа к данным являются невизуальными.
Для создания нового проекта достаточно выбрать команду New Application из меню File или воспользоваться Репозиторием объектов, который открывается командой New из меню File.
 Примечание
Здесь рассматривается простейший вариант создания приложения. В реальных проектах для размещения компонентов доступа к данным следует использовать модуль данных.
Затем на форму нового проекта необходимо перенести компонент, инкапсулирующий набор данных, и выполнить следующие действия. Последовательность действий рассмотрим для компонента, инкапсулирующего функции таблицы (см. гл. 12).
1. Подключить компонент к базе данных. Для этого, в зависимости от конкретной технологии, используется или специальный компонент, устанавливающий соединение, или прямое обращение к драйверу, интерфейсу или динамической библиотеке. Детально способы соединения рассматриваются в части IV.
2. Подключить к компоненту таблицу БД. Для этого используется свойство TableName, доступное в Инспекторе объектов. После выполнения действий первого этапа в списке этого свойства должны появиться имена всех доступных в подключенной базе данных таблиц. После выбора имени таблицы в свойстве TableName компонент оказывается связанным с ней.
3. Переименовать компонент. Это не обязательное действие. Тем не менее, в любых случаях желательно присваивать компонентам доступа к данным осмысленные имена, соответствующие названиям подключенных таблиц. Обычно название компонента копирует название таблицы (например, Orders или OrdTable илт tblOrders).
4. Активизировать связь между компонентом и таблицей БД. Для этого используется свойство Active. Если в Инспекторе объектов присвоить этому свойству значение True, то связь активизируется. Эту операцию можно выполнить и в исходном коде приложения. Также существует метод open, который открывает набор данных, и метод close, закрывающий его.
В качестве примера попробуем создать простейшее приложение баз данных, работающее с таблицей COUNTRY.DB из стандартной демонстрационной базы данных DBDEMOS через драйвер процессора Borland Database Engine.
На форму нового проекта необходимо перенести компонент TTаblе со страницы BDE Палитры компонентов. Свойство DatabaseName должно ссылаться на псевдоним DBDEMOS, который создается автоматически при установке Delphi, его можно выбрать из списка свойства DatabaseName. Для свойства TableName необходимо задать имя таблицы "COUNTRY.DB". Его также можно выбрать из списка. Двойной щелчок на свойстве Active в Инспекторе объектов присваивает ему значение True. После этого связь компонента с таблицей активизируется. Свойство Name имеет значение "CountryTable".
Открытие и закрытие набора данных можно предусмотреть как реакцию на действия пользователя или возникновение события. Чаще всего набор данных должен открываться при первом показе формы и закрываться при ее закрытии.
 Листинг 11.1. Секция Implementation главного модуля проекта DemoDBApp 
implementation
 {$R *.DFM}
procedure TForml.FormShowfSender: TObject);
begin
 try
CountryTable.Open;
 except
ShowMessage('Table open error');
 end; 
end;
procedure TForml.FormClose(Sender: TObject; var Action: TCloseAction); 
begin
CountryTable.Close; 
end;
end.
При открытии формы выполняется метод обработчик FormShow. В нем набор данных открывается при помощи метода Open. Обратите внимание на использование конструкции try..except, которая обеспечивает корректное завершение при возникновении исключительных ситуаций.
Так как ошибки в работе приложений баз данных могут привести к серьезным последствиям (потеря или искажение данных), то защитный код должен присутствовать во всех критических местах.
В методе-обработчике FormClose, который вызывается при закрытии формы, набор данных закрывается методом close.
Примечание 
В принципе, для выполнения рассмотренных операций можно воспользоваться и свойством Active. Однако реальные операции выполняют указанные методы. Поэтому использование свойства является лишним этапом, да и с точки зрения ООП все действия должны выполнять методы объекта, а свойства служат только для представления значений. Свойство Active сигнализирует о состоянии набора данных.
Настройка компонента TDataSource
На втором этапе разработки приложения баз данных необходимо перенести на форму и настроить компонент TDataSource. Он обеспечивает взаимодействие набора данных с компонентами отображения данных. Чаще всего одному набору данных соответствует один компонент TDataSource, хотя их может быть несколько.
Для настройки свойств компонента необходимо выполнить следующие действия.
1. Связать набор данных и компонент TDataSource. Для этого используется свойство DataSet компонента TDataSource, доступное через Инспектор объектов. Это указатель на экземпляр компонента доступа к данным. В списке этого свойства в Инспекторе объектов перечислены все доступные компоненты наборов данных.
2. Переименовать компонент. Это не обязательное действие. Тем не менее желательно присваивать компонентам осмысленные имена, соответствующие названиям связанных наборов данных. Обычно название компонента комбинирует имя набора данных (например OrdSource или dsOrders).
В приложении DemoDBApp компонент countrysource связан с компонентом CountryTable. Поэтому свойство DataSet имеет значение CountryTable.
 Примечание
Компонент TDataSource можно подключить не только к набору данных из той же формы, но и любой другой, модуль которой указан в секции uses.
Компонент TDataSource имеет ряд полезных свойств и методов. Итак, связывание с компонентом набора данных выполняет свойство
property DataSet: TDataSet;
а определить текущее состояние набора данных можно, использовав свойство
type TDataSetState = (dslnactive, dsBrowse, dsEdit, dslnsert, dsSetKey, dsCalcFields, dsFilter, dsNewValue, dsOldValue, dsCurValue, dsBlockRead, dsInternalCalc); property State: TDataSetState;
При помощи свойства
property Enabled: Boolean;
можно включить или отключить все связанные визуальные компоненты. При значении False ни один связанный компонент отображения данных не будет работать.
Свойство
property AutoEdit: Boolean;
при значении True всегда будет переводить набор данных в режим редактирования при получении фокуса одним из связанных визуальных компонентов.
Аналогично, метод
procedure Edit;
переводит связанный набор данных в режим редактирования.
Метод
function IsLinkedTo(DataSet: TDataSet): Boolean;
возвращает значение True, если компонент, указанный в параметре DataSet, действительно связан с данным компонентом TDataSource.
Метод-обработчик
type TDataChangeEvent = procedure(Sender: TObject; Field: TField)
of object;
property OnDataChange: TDataChangeEvent;
вызывается при редактировании данных в одном из связанных визуальных компонентов.
Метод-обработчик
property OnUpdateData: TNotifyEvent;
вызывается перед сохранением изменений в базе данных. Метод-обработчик
property OnStateChange: TNotifyEvent;
вызывается при изменении состояния связанного набора данных (см. гл. 12).
 
Отображение данных
На третьем этапе создания приложения баз данных необходимо разработать пользовательский интерфейс на основе компонентов отображения данных. Эти компоненты предназначены специально для решения задач просмотра и редактирования данных. Внешне большинство этих компонентов ничем не отличаются от стандартных элементов управления. Более того, многие из компонентов отображения данных являются наследниками стандартных компонентов — элементов управления.
Компоненты отображения данных должны быть связаны с компонентом TDataSource и через него с компонентом набора данных. Для этого используется их свойство DataSource. Оно присутствует во всех компонентах отображения данных.
Большинство компонентов предназначены для представления данных из одного единственного поля. В таких компонентах имеется еще одно свойство DataField, которое определяет поле связанного набора данных, отображаемое в компоненте.
Особое значение для приложений баз данных играет компонент TOBGrid, который представляет данные в виде таблицы. В столбцах таблицы размещаются поля набора данных, а в строках — записи. Для этого компонента не имеет смысла определять конкретное поле, но можно задать настраиваемый набор колонок, а для каждой из них определить поле набора данных. (Подробнее о визуальных компонентах отображения данных см. гл. 15.)
Таким образом, для каждого визуального компонента отображения данных необходимо выполнить следующие операции:
1. Связать компонент отображения данных и компонент TDataSource. Для этого используется свойство Datasource, которое должно указывать на экземпляр требуемого компонента TDataSource. Один компонент отображения данных можно связать только с одним компонентом TDataSource. Необходимый компонент можно выбрать в списке свойств в Инспекторе объектов.
2. Задать поле данных. Для этого используется свойство DataField типа TFields. В нем необходимо указать имя поля связанного набора данных. После задания свойства Datasource поле можно выбрать из списка. Этот этап применяется только для компонентов, отображающих единственное поле.
Отдельное место среди компонентов отображения данных занимает компонент TDBNavigator. Он предназначен для перемещения по записям набора данных.
В приложении DemoDBApp использованы компоненты TDBGrid, TDBNavigator и TDBEdit (3).
Все три компонента отображения данных связаны с компонентом CountrySource типа TDataSource при помощи свойства DataSource.
Компонент TDBEdit отображает данные из поля capital (столица государства) и позволяет редактировать их.
Компонент TDBGrid показывает набор данных целиком, данные в ячейках можно редактировать.
Компонент TDBNavigator позволяет перемещаться по записям набора данных CountryTable. При этом результат заметен во всех подключенных к набору данных компонентах отображения данных.
 
Резюме
Приложения баз данных могут получать доступ к источникам данных при помощи разнообразных технологий доступа, многие из которых используются и в приложениях Delphi. Тем не менее любое приложение баз данных в Delphi имеет стандартное ядро, структура которого определена архитектурой приложения баз данных.
Набор базовых компонентов и способов разработки является единой основой, на которой базируются технологии доступа к данным. Это позволило унифицировать процесс разработки приложений баз данных.
В основе процесса разработки лежит триада компонентов:

  •  невизуальные компоненты набора данных;
  •  невизуальные компоненты TDataSource;

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

 

 
На главную | Содержание | < Назад....Вперёд >
С вопросами и предложениями можно обращаться по nicivas@bk.ru. 2013 г. Яндекс.Метрика