Опубликован: 07.05.2010 | Уровень: специалист | Доступ: свободно
Лекция 28:

Многоуровневая архитектура

< Лекция 27 || Лекция 28: 12 || Лекция 29 >

Поясним материал на схеме:

Поведение сервера в зависимости от способа создания экземпляров

Рис. 28.4 . Поведение сервера в зависимости от способа создания экземпляров

Нажмите кнопку "ОК", окно Мастера создания удаленного модуля закроется, и у нас появится модуль данных MyRDM. Сохраните его на диск под именем RDM.

В этот контейнер с вкладки ADO поместите компонент ADOConnection и две таблицы ADOTable. Щелкните дважды по ADOConnection, чтобы открыть редактор подключений. Нажмите кнопку Build, чтобы открылся список поставщиков данных. Здесь выберем " Microsoft Jet 4.0 OLE DB Provider " и нажмем копку "Далее". В следующем окне, в поле 1 поместим адрес и имя файла (вы уже поместили файл по этому адресу?):

C:\DataBases\ok.mdb

Как видите, локальную базу данных мы превращаем в распределенную, предназначенную для подключения многих клиентов, что гораздо удобней и надежней файл-серверной архитектуры.

Далее нажимаем "ОК" и закрываем редактор подключений. Свойство LoginPrompt компонента переведем в False, чтобы при подключении не выходило запроса на имя пользователя и пароль. А свойство Connected переведем в True, чтобы физически подключить компонент к базе данных.

Займемся табличными компонентами. В обеих ADOTable в свойстве Connection выберите наш ADOConnection1. У первой таблицы в свойстве TableName выберите таблицу LichData, а свойство Name переименуйте в TLichData. У второй таблицы в свойстве TableName выберите таблицу Telephones, а свойство Name переименуйте в TTelephones. Свойство Active обеих таблиц переведите в True, чтобы открыть эти наборы данных. Как видите, пока что подключение сервера к базе данных мало отличается от того, что мы проходили во второй лекции, при разработке локальной базы данных для отдела кадров. Однако дальше начинаются различия.

Как вы помните, посредником между НД и компонентами отображения данных является компонент DataSource. Однако в серверном приложении у нас нет компонентов отображения данных, поэтому компоненты DataSource для этого нам не нужны. Однако нам нужно будет организовать связь таблиц один-ко-многим, а для этого один DataSource нам все-таки понадобится.

Также нам понадобится посредник для связи с клиентским приложением, и этим посредником является компонент DataSetProvider, который находится на вкладке Data Access Палитры компонентов. Такой компонент требуется устанавливать к каждому набору данных ( Table или Query ), с которым будет соединяться клиентское приложение. Установите в контейнер MyRDM два таких компонента. У первого свойство Name переименуйте в DSPLichData, а в свойстве DataSet выберите таблицу TLichData. У второго свойство Name переименуйте в DSPTelephones, а в свойстве DataSet выберите таблицу TTelephones.

Теперь установим связь главная-подчиненная между таблицами, для этого установите один компонент DataSource. Его свойство Name переименуйте в dsLichData, а в свойстве DataSet выберите таблицу TLichData. Организация связи производится в таблице TTelephones. В ее свойстве MasterSource выберите dsLichData, затем раскройте сложное свойство MasterFields. Откроется окно редактора связи:

Редактор связей

Рис. 28.5 . Редактор связей

В разделе подчиненного поля выберите "Сотрудник", в разделе главного поля - "Ключ", нажмите кнопку Add, чтобы создать связь, и кнопку OK, чтобы подтвердить это. Внешний вид полученного контейнера представлен на рисунке ниже:

 Удаленный модуль данных

Рис. 28.6. Удаленный модуль данных

Это все, сервер приложений готов. Как видите, даже не пришлось подключать удаленный модуль данных к главной форме командой File -> Use Unit. Сохраните проект и командой Run -> Run (или кнопкой Run на панели инструментов) скомпилируйте и загрузите полученную программу. При этом произошли две вещи: проект скомпилировался в выполняемую программу, а при первом запуске наш сервер зарегистрировался в реестре Windows. Теперь Windows знает, где находится наш сервер, и при необходимости сможет его автоматически загрузить.

К слову сказать, при переносе серверного файла на другой ПК нет необходимости даже загружать эту программу, чтобы прописать ее в реестре Windows, достаточно из командной строки загрузить ее с параметром / regserver, при этом программа лишь пропишется в реестре и сразу отключится. А для удаления регистрации этого сервера из реестра нужно загрузить его с параметром / unregserver, например, так (у вас может быть другой адрес):

C:\ MyNewServer\ MyNewServer.exe /unregserver

Однако не забудьте, что для дальнейшей правильной работы он должен быть прописан в реестре Windows. Поэтому если сейчас вы удалили сервер из реестра, вновь загрузите программу MyNewServer.exe, чтобы заново прописать ее.

Как уже упоминалось, для правильной работы серверов DCOM на серверном ПК должна быть установлена и зарегистрирована библиотека midas.dll. В нашем случае этого делать не нужно, так как при установке Delphi библиотека устанавливается и регистрируется автоматически. Однако если вы будете использовать созданный сервер приложений на другом ПК, где не устанавливалась Delphi, то зарегистрировать библиотеку придется вручную. Для этого на вашем ПК нужно найти файл библиотеки, он устанавливается по адресу (для Windows XP ):

C:\Windows\System32

Этот файл нужно скопировать на ПК, который вы собираетесь использовать в качестве сервера, по этому же адресу. В этой же папке находится утилита regsvr32.exe, которая предназначена для регистрации библиотек *.dll. Чтобы зарегистрировать нашу библиотеку, надо из командной строки (или в окне команды Пуск -> Выполнить) вызвать утилиту, передав ей в качестве параметра имя библиотеки:

C:\Windows\System32\regsvr32 midas.dll

Таким образом, мы зарегистрируем библиотеку в реестре. Снять регистрацию можно командой:

C:\Windows\System32\regsvr32 /u midas.dll

Не снимайте регистрацию на вашем ПК, иначе потом вы не сможете загрузить сервер приложений!

Если в качестве источника данных вы будете использовать сервер InterBase, то набор компонентов в удаленном модуле данных, скорее всего, будет с вкладки InterBase, а их подключение к базе данных будет таким же, как мы изучали в прошлых лекциях.

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

Таблица 28.1 . Свойства компонента DataSetProvider
Свойство Описание
Constraints Если содержит True, клиенту пересылается информация о наложенных на данные ограничениях. Клиент имеет возможность организовать локальный контроль данных.
DataSet Содержит имя связанного с компонентом набора данных ( TTable, TQuery, TStoredProc )
Exported При значении True клиент имеет возможность использовать интерфейс IAppServer при обращении к провайдеру.
Options Сложное раскрывающееся свойство. Определяет, какие данные будут включены в передаваемый клиенту пакет. Подробнее о параметрах этого свойства смотрите следующую таблицу.
ResolveToDataSet Определяет, как обновляются данные. Если содержит True - то в НД, указанном в свойстве DataSet. Иначе - непосредственно в серверной БД.
UpdateMode Определяет критерии поиска записи в наборе данных при сохранении изменений этой записи клиентом. Если значение upWhereAll, поиск записи ведется по всем полям; если upWhereChanged - по ключевым и измененным полям; если upWhereKeyOnly - только по ключевым полям.

Таблица 28.2 . Параметры свойства Options компонента DataSetProvider
Параметр Описание
poFetchBlobsOnDemand По умолчанию, данные из BLOB полей клиенту не пересылаются, чтобы излишне не загружать трафик. Если свойство содержит True - данные пересылаются. Иначе, эта возможность отключена, и чтобы получить BLOB -данные записи, клиентское приложение должно явно использовать метод FetchBlobs.
poFetchDetailsOnDemand Данные из вложенных или подчиненных таблиц не включаются в пакет. Чтобы их получить, клиентское приложение использует метод FetchDetails. Если свойство имеет значение True, то эти данные включаются в пакет автоматически.
poIncFieldProps В пакет включаются такие свойства полей, как Alignment, DisplayLabel, DisplayWidth, Visible, DisplayFormat, EditFormat, MaxValue, MinValue, Currency, EditMask, DisplayValues.
poCascadeDeletes Дает серверу распоряжение автоматически удалять каскадным методом записи из подчиненных таблиц, если пользователь удалил связанную с ними запись в главной таблице.
poCascadeUpdates Дает серверу распоряжение автоматически изменять каскадным методом записи из подчиненных таблиц, если пользователь изменил связанную с ними запись в главной таблице.
poReadOnly Данные клиенту предоставляются только для чтения.
poAllowMultiRecordUpdates Параметр допускает индивидуальные обновления сразу нескольких записей. Если параметр = False, множественные обновления будут автоматически прерваны.
poDisableInserts Параметр запрещает клиенту вставку новых записей.
poDisableEdits Параметр запрещает клиенту редактирование записей.
poDisableDeletes Параметр запрещает клиенту удаление записей.
poNoReset Запрещает обновление набора данных сервера перед передачей записей клиенту.
poAutoRefresh Разрешает автоматическое обновление записей клиента при их изменении. Для ускорения работы эта опция по умолчанию отключена.
poPropogateChanges Обновления, сделанные в событиях BeforeUpdateRecord или AfterUpdateRecord передаются клиенту в пакете, и объединяются с клиентским набором данных.
poAllowCommandText Предоставляет клиенту возможность отменить НД, заменяя его НД, полученным SQL -запросом.
poRetainServerOrder Запрещает клиенту изменять сортировку записей, полученную по умолчанию.

Таблица 28.3 . Некоторые полезные методы компонента DataSetProvider
Метод Описание
ApplyUpdates Обновляет данные. Имеет параметры: Delta - измененные, новые или удаленные записи; MaxError - максимальное количество ошибок, при котором обновление прекращается (0 - не ограничено); ErrorCount - количество допущенных ошибок. Метод возвращает клиенту набор записей, при обновлении которых произошла ошибка.
DoDelete Вызывается для каждой записи, которая должна быть удалена.
DoInsert Вызывается для каждой новой записи.
DoUpdate Вызывается для каждой модифицированной записи.
EndUpdate Вызывается в момент завершения обновлений.
LogUpdateError Добавляет ошибочную запись в журнал ошибок, который затем передается клиентскому приложению.

На следующей лекции мы подробно разберем создание клиентской части многоуровневых приложений.

< Лекция 27 || Лекция 28: 12 || Лекция 29 >
Евгений Медведев
Евгений Медведев

В лекции №2 вставляю модуль данных. При попытке заменить name на  fDM выдает ошибку: "The project already contains a form or module named fDM!". Что делать? 

Анна Зеленина
Анна Зеленина

При вводе типов успешно сохраняется только 1я строчка. При попытке ввести второй тип вылезает сообщение об ошибке "project mymenu.exe raised exception class EOleException with message 'Microsoft Драйвер ODBC Paradox В операции должен использоваться обновляемый запрос'.