Секреты Delphi. Использование TClientDataset в двухуровневых приложениях
Секреты Delphi. Использование TClientDataset в двухуровневых приложениях
В далеком августе 2000 г. была опубликована очень интересная статья Дана Мишера (Dan Miser) "ClientDataset as a Replacement for Cached Updates", посвященная возможности применения компоненты TCli-entDataset в двухуровневых приложениях без необходимости приобретения MIDAS-лицензии.
Оригинал статьи можно найти по адресу http://community.borland.com/article/0,1410,22571,00.html . В статье предлагалось использовать связку TClientDataset-TProvider-TDataset в рамках одного приложения. Во-первых, данная технология позволяет создать макет приложения, используя традиционную двухуровневую модель с возможностью последующего выделения отдельного уровня бизнес-логики. Во-вторых, компонента TClientDataset предоставляет ряд очень удобных дополнительных возможностей. К слову сказать, в последних версиях Delphi данная идея трансформировалась в компоненту TSimpleDataset палитры dbEx-press. По сути, это все та же связка TClientDataset-TProvider-TDataset в одном флаконе.
Наши первые попытки написать трехуровневое приложение не увенчались успехом. Проект было очень сложно отлаживать, т.к. постоянно приходилось переключаться между клиентским и серверным проектом. По прочтении вышеназванной статьи было решено попробовать данную технологию с последующим разделением бизнес-логики.
Уровень физического доступа к серверу базы данных был вынесен в отдельный модуль данных DataModule. Забегая вперед, хочется отметить, что это в дальнейшем позволило заменить все компоненты доступа к серверу базы данных на более продвинутые без затрагивания основного приложения. Фактически можно создать несколько различных модулей для различных серверов баз данных. К сожалению, все имеет свою цену. При использовании компонент-посредников несколько увеличивается общее время выполнения запросов, так как требуется время на передачу данных между компонентами. Тем не менее, если в вашем приложении перекачиваются столь существенные объемы данных, способные вызвать значительные задержки, то, пожалуй, стоит задуматься об архитектуре приложения.
Несмотря на ложку дегтя, обилие появившихся возможностей с лихвой компенсирует недостатки. К примеру, при традиционном подходе для сортировки набора данных требуется перегенерировать запрос, поменяв выражение "ORDER BY" и перечитать данные с сервера. При этом увеличивается сетевой трафик, загрузка сервера и соответственно время отклика системы. TClientData-set позволяет создавать индексы в оперативной памяти на лету с возможностью сортировки и быстрого поиска на стороне клиента. К тому же, в TClientDataset встроен механизм расширенных фильтров, которые позволяют выполнять отбор данных по традиционно серверным выражениям — например, LIKE и IN (Memo LIKE '%filters%' и соответственно Day(DateField) IN (1,7)), которые выполняются аналогично синтаксису SQL 92. Для многих интересной может оказаться возможность вычисления агрегативных значений на стороне клиента. При этом агрегативные поля можно группировать по заданным критериям.
Ориентирование на автономную работу клиентов вылилось в возможность сохранения полученного набора данных во внешний бинарный или XML-файл. Эта функция позволяет организовать работу "по старинке" с таблицами без SQL. Но более интересна возможность сохранения текущего состояния данных на клиенте при потере соединения с сервером базы данных — так называемая "модель портфеля". Возможность сохранения наборов данных можно также использовать для кэширования на стороне клиента редко изменяемых наборов данных. Это порой позволяет существенно повысить производительность системы.
Но самой интересной возможностью TClientDataset является способность редактировать традиционно Read Only наборы данных. Примером может быть запрос вида:
select O.OrdId, O.OrderDate, O.CustId
,C.Name as CustomerName
,sum(I.Qty * I.ActualPrice) as ItemSum
from ORD O, Customer C, Item I
where O.CustId = C.CustId
and O.OrdId = I.OrdId(+)
group by O.OrdId, O.OrderDate, O.CustId, C.Name
Этот запрос представляет собой выборку по списку ордеров, которая включает агрегативные поля и поля подстановки. Использование TClientData-set позволяет с минимальными трудозатратами организовать корректировку полученного заданным запросом ордера.
Дополнительно хочется заметить, что все изменения на клиентской стороне кэшируются, и на сервер отправляются только данные о реальных изменениях. На практике это означает, что, если вы внесли какие-либо изменения, а потом исправили их на начальные значения, то на сервер ничего отправляться не будет. Это свойство также снижает загрузку сети и сервера базы данных.
Продолжение следует.
Сергей Бердачук, Berdachuk@tut.by,
http://berdachuk.at.tut.by
В далеком августе 2000 г. была опубликована очень интересная статья Дана Мишера (Dan Miser) "ClientDataset as a Replacement for Cached Updates", посвященная возможности применения компоненты TCli-entDataset в двухуровневых приложениях без необходимости приобретения MIDAS-лицензии.
Оригинал статьи можно найти по адресу http://community.borland.com/article/0,1410,22571,00.html . В статье предлагалось использовать связку TClientDataset-TProvider-TDataset в рамках одного приложения. Во-первых, данная технология позволяет создать макет приложения, используя традиционную двухуровневую модель с возможностью последующего выделения отдельного уровня бизнес-логики. Во-вторых, компонента TClientDataset предоставляет ряд очень удобных дополнительных возможностей. К слову сказать, в последних версиях Delphi данная идея трансформировалась в компоненту TSimpleDataset палитры dbEx-press. По сути, это все та же связка TClientDataset-TProvider-TDataset в одном флаконе.
Наши первые попытки написать трехуровневое приложение не увенчались успехом. Проект было очень сложно отлаживать, т.к. постоянно приходилось переключаться между клиентским и серверным проектом. По прочтении вышеназванной статьи было решено попробовать данную технологию с последующим разделением бизнес-логики.
Уровень физического доступа к серверу базы данных был вынесен в отдельный модуль данных DataModule. Забегая вперед, хочется отметить, что это в дальнейшем позволило заменить все компоненты доступа к серверу базы данных на более продвинутые без затрагивания основного приложения. Фактически можно создать несколько различных модулей для различных серверов баз данных. К сожалению, все имеет свою цену. При использовании компонент-посредников несколько увеличивается общее время выполнения запросов, так как требуется время на передачу данных между компонентами. Тем не менее, если в вашем приложении перекачиваются столь существенные объемы данных, способные вызвать значительные задержки, то, пожалуй, стоит задуматься об архитектуре приложения.
Несмотря на ложку дегтя, обилие появившихся возможностей с лихвой компенсирует недостатки. К примеру, при традиционном подходе для сортировки набора данных требуется перегенерировать запрос, поменяв выражение "ORDER BY" и перечитать данные с сервера. При этом увеличивается сетевой трафик, загрузка сервера и соответственно время отклика системы. TClientData-set позволяет создавать индексы в оперативной памяти на лету с возможностью сортировки и быстрого поиска на стороне клиента. К тому же, в TClientDataset встроен механизм расширенных фильтров, которые позволяют выполнять отбор данных по традиционно серверным выражениям — например, LIKE и IN (Memo LIKE '%filters%' и соответственно Day(DateField) IN (1,7)), которые выполняются аналогично синтаксису SQL 92. Для многих интересной может оказаться возможность вычисления агрегативных значений на стороне клиента. При этом агрегативные поля можно группировать по заданным критериям.
Ориентирование на автономную работу клиентов вылилось в возможность сохранения полученного набора данных во внешний бинарный или XML-файл. Эта функция позволяет организовать работу "по старинке" с таблицами без SQL. Но более интересна возможность сохранения текущего состояния данных на клиенте при потере соединения с сервером базы данных — так называемая "модель портфеля". Возможность сохранения наборов данных можно также использовать для кэширования на стороне клиента редко изменяемых наборов данных. Это порой позволяет существенно повысить производительность системы.
Но самой интересной возможностью TClientDataset является способность редактировать традиционно Read Only наборы данных. Примером может быть запрос вида:
select O.OrdId, O.OrderDate, O.CustId
,C.Name as CustomerName
,sum(I.Qty * I.ActualPrice) as ItemSum
from ORD O, Customer C, Item I
where O.CustId = C.CustId
and O.OrdId = I.OrdId(+)
group by O.OrdId, O.OrderDate, O.CustId, C.Name
Этот запрос представляет собой выборку по списку ордеров, которая включает агрегативные поля и поля подстановки. Использование TClientData-set позволяет с минимальными трудозатратами организовать корректировку полученного заданным запросом ордера.
Дополнительно хочется заметить, что все изменения на клиентской стороне кэшируются, и на сервер отправляются только данные о реальных изменениях. На практике это означает, что, если вы внесли какие-либо изменения, а потом исправили их на начальные значения, то на сервер ничего отправляться не будет. Это свойство также снижает загрузку сети и сервера базы данных.
Продолжение следует.
Сергей Бердачук, Berdachuk@tut.by,
http://berdachuk.at.tut.by
Компьютерная газета. Статья была опубликована в номере 17 за 2004 год в рубрике программирование :: delphi