|
|
|||||||||||||||||||||||||||||
|
Компоненты ADOДмитрий Ю. Сидоров
В Delphi 5.0 появились компоненты для работы с Microsoft® ActiveX® Data Objects (далее ADO). ADO это технология стандартного обращения к реляционным данным от Microsoft. Эта технология аналогична BDE по назначению и довольно близка по возможностям. Следует отличать компоненты Delphi, являющиеся частью библиотеки визуальных компонентов Delphi (VCL), и интерфейсы и объекты ADO, которые в них инкапсулированы. В дальнейшем, когда упоминается компонент - это компонент Delphi, а когда объект или интерфейс - это объект или интерфейс ADO. Обзор компонент Для работы с ADO на вкладке компонентов ADO есть шесть компонентов: TADOConnection, TADOCommand, TADODataSet, TADOTable, TADOQuery, TADOStoredProc. Рис. 0. Палитра компонент ADO
Разница между ними в том, что команда, исполняемая через TADODataSet, должна возвращать набор данных и этот компонент позволяет работать с ними средствами Delphi (например, привязать компонент типа TDataSource). А компонент TADOCommand позволяет исполнять команды не возвращающие набор данных, но не имеет штатных средств Delphi для последующего использования возвращенного набора данных. Очевидно, что все компоненты должны связываться с базой данных. Делается это двумя способами либо через компонент TADOConnection либо прямым указанием базы данных в остальных компонентах. К TADOConnection остальные компоненты привязываются с помощью свойства Connection, к базе данных напрямую через свойство ConnectionString. База данных может быть указана двумя способами через файл линка к данным (файл в формате Microsoft Data Link, расширение UDL), либо прямым заданием параметров соединения. Значение свойства всех ConnectionString этих компонент могут быть введены напрямую в текстовой форме, но куда проще вызвать редактор свойства нажав на кнопку "…" в конце поля ввода. Окно этого свойства выглядит так: Рис. 1. При выборе "Use data link file" и нажатии на кнопку "Browse…" появляется стандартный диалог выбора файла. Этот файл можно создать в любом окне explorer-а (в этом окне открытия файла, в самом explorer, на desktop и т.д.) вызвав контекстное меню и выбрав пункт "New/Microsoft Data Link". Потом вызовите локальное меню для созданного файла и выберите в нем пункт "Open". После этого появится property sheet описанный чуть ниже. Эти же вкладки содержит и property sheet, вызываемый через пункт "Property" локального меню UDL файла, но в нем еще есть вкладки относящиеся к самому файлу. Использование файлов Microsoft Data Link упрощает поддержку приложений, так как возможно использовать средства Windows для настройки приложения. При выборе в редакторе свойства "Use connection string" и нажатии на кнопку "Build…" появляется такой же property sheet, как и при выборе "Open" для Microsoft Data Link файла. В этом окне выбирается тип базы данных, местоположение базы и параметры соединения. На первой странице выбирается тип базы данных или Provider, в терминах ADO. Рис. 2. Базы MS Access доступны как через "Microsoft Jet OLE DB Provider", так и через "Microsoft OLE DB Provider for ODBC". Следующая страница зависит от выбранного типа базы, однако для всех типов есть кнопка "Test connection" позволяющая проверить правильность и полноту параметров. Для "Microsoft Jet OLE DB Provider" она выглядит так: Рис. 3. Checkbox "Blank password" подавляет диалог ввода идентификатора и пароля пользователя при установлении соединения, если поле пароля пустое. Checkbox "Allow saving password" сохраняет пароль в строке параметров соединения. Если он не отмечен, то введенный пароль будет использоваться только при выполнении тестового соединения. Для "Microsoft OLE DB Provider for ODBC" эта страница выглядит так: Рис. 4. Радиокнопка "Use data source name" позволяет ввести предустановленный алиас ODBC, а через "Use connection string" вводится как алиасы так и тип ODBC драйвера и параметры соединения. Параметры идентификации пользователя аналогичны выше описанным. На странице "Advanced" расположены дополнительные параметры, с помощью которых устанавливается уровень доступа к файлу базы данных, таймаут сетевого соединения (то есть время через которое связь будет считаться потерянной, если сервер не отвечает) и уровень глубины проверки секретности соединения. Рис. 5. На странице "All" можно отредактировать все параметры с предыдущих страниц и параметры зависящие от провайдера, но не вошедшие на страницу "Connection". Редактирование осуществляется в виде параметр - значение, причем в текстовой форме, никаких диалогов нет. Помощи то же нет, эти параметры описаны только в документации на провайдер. Ее можно найти в MSDN Data Access Services/Microsoft Data Access Components (MDAC) SDK/Microsoft ActiveX Data Objects (ADO)/Microsoft ADO Programmer's Reference/Using Providers with ADO. Рис. 6. В компоненте TADOConnection есть свойства Provider, DefaultDatabase и Mode которые являются альтернативным методом задания частей строки параметров соединения - провайдера, базы данных (например, пути до базы MS Access) и режима совместного использования файлов базы данных. Эти значение этих свойств автоматически включаются в строку соединения, если были заданы до активизации компонента и автоматически выставляются после соединения. * Прим. ред. Компоненты StoredProc (и BDE и IB) могут возвращать набор данных, являются потомками TDataSet и могут выступать источником данных в компонентах типа TdataSource. Простейшее приложение
Рис 7
Теперь нам необходимо указать базу данных. Делается это в свойстве ConnectionString компонента TADOTable. При нажатии на кнопку "…" появится редактор параметров соединения. Отметим радокнопку "Use data link file", нажмите на кнопку "Browse…" и выберите в появившемся окне после файл линка к базе данных "\Program Files\Common Files\System\ole db\Data Links\DBDEMOS.UDL". Этот линк указывает на базу в формате MS Access, входящую в поставку Delphi. После этого в свойстве TableName компонента TADOTable выберем таблицу customer. Активизируем компонента TADOTable, установив свойство Active в True. Приложение можно запускать. Этот пример можно найти в директории Simple. Обзор ADO ADO основано на технологии COM. Все объекты и интерфейсы ADO являются интерфейсами и объектами COM. Рис 8. Архитектура ADO Интерфейс Connection Объекты этого типа выполняют следующие функции:
Рис 9. Схема взаимодействия в ADO основных COM интерфейсов Интерфейсы Recordset и Field Интерфейс Recordset (на нижнем уровне ADO это IRowset) является аналогом TDataSet в Delphi. Поддерживает текущее положение и перемещение курсора, закладки (bookmarks), чтение, изменение и удаление записей и так далее. Значение полей и их типы доступны с помощью свойства Fields. Интерфейс Field позволяет получать значение поля, его тип длину и так далее. Интерфейсы Command и Parameter Эти два типа позволяют работать с командами источника данных. Синтаксис команд для каждого из источников свой. Интерфейс Property Все объекты, кроме Parameter, имеют свойство Properties, которое позволяет получать и устанавливать параметры специфические для провайдера данных. Библиотека довольно запутанная, многие функции дублированы в разных объектах. Например, Recordset можно создавать напрямую, методом Open, (причем предварительно создавать Connection не обязательно), можно получить как результат выполнения метода Command.Execute, либо после Connection.Execute задав команду без параметров. Интерфейс Command инкапсулирован во все компоненты за исключением TADOConnection. Это сделано потому, что в ADO нет возможности получить данные не выполнив команду. Интерфейс Recordset инкапсулирован в компоненты производные от TCustomADODataSet. Это компоненты TADODataSet, TADOTable, TADOQuery, TADOStoredProc.Получать данные из них возможно штатными средствами Delphi. Возможно получение данных и при выполнении компонента TADOCommand. Метод этого компонента Execute возвращает тип _Recordset. После чего его можно, например, связать с компонентом TADODataSet следующим образом ADODataSet1.RecordSet := ADOCommand1.Execute; Компоненты TADOTable, TADOQuery и TADOStoredProc являются частными случаями команды, соответственно для таблицы, SQL запроса и хранимой процедуры. Тип Connection инкапсулируется в компонент TADOConnection. Когда вы выполняете команду предварительно не открывая соединение, оно все равно создается. Получить к нему доступ возможно через свойство Recordset. Привязать компонент TADOConnection к уже открытому соединению возможно через свойство ConnectionObject. Информацию о структуре базы данных можно получить с помощью метода OpenSchema компонента TADOConnection. Эта информация представлена как набор таблиц, как стандартизованных, так и специфических для провайдера. Таким способом можно узнать список таблиц, запросов, хранимых процедур и многое другое. Однако изменять структуру базы с помощью возвращаемых наборов данных невозможно. Пример использования TADOConnection В этом примере рассматривается работа с компонентом TADOConnection, SQL запросами с параметрами и трансакциями. Создадим приложение из следующих компонентов
Рис 10. Master-detail форма на этапе дизайна Связываем MasterGrid, MasterDS,MasterSQL и DetailGrid,DetailDS,DetailSQL аналогично предыдущему примеру, за исключением того, что вместо типа TADOTable используется тип TADODataSet. Привязываем Connect к базе данных. Для этого в редакторе свойства ConnectionString выбираем ту же базу данных, что и в предыдущем примере. Для ввода SQL запросов необходимо отредактировать свойство CommandText компонентах MasterSQL и DetailSQL. После нажатия на кнопку "…" появится редактор компонент, который выглядит следующим образом Рис. 10 Кнопка "Add Table to SQL" добавляет в текст SQL запроса таблицу, выбранную в списке "Tables", а "Add Field to SQL" поле таблицы, выбранное в списке "Fields". Запрос для MasterSQL select VendorNo, VendorName, Country, City, State, Preferred from vendors Запрос в DetailSQL должен выбирать только те детали, поставщик которых является текущим в MasterSQL. Для этого установим свойство DataSource компонента DetailSQL в значение MasterDS. Запрос для DetailSQL следующий: select PartNo, OnOrder, OnHand, ListPrice, Description, Cost from parts where VendorNo = :VendorNo :VendorNo в части where - параметр запроса. Параметры при установленном DataSource берутся из него. Активизируем MasterSQL и DetailSQL аналогично предыдущему примеру. Приложение можно запускать. Этот пример можно найти в директории MasterDetail. Пример использования параметров запроса Теперь ограничим выборку поставщиков по значению поляState. Для этого добавим к форме следующие компоненты StateEdit типа TEdit c вкладки Standard, QueryButton типа TButton c вкладки Standard Изменим запрос в MasterSQL на select VendorNo, VendorName, Country, City, State, Preferred from vendors where State = :StateID :StateID - параметр, вместо которого при выполнении подставляется значение. Добавим так же обработчик события OnClick в QueryButton следующего содержания procedure TForm1.QueryButtonClick(Sender: TObject); begin MasterSQL.Active := False; DetailSQL.Active := False; MasterSQL.Parameters.ParamByName('StateID').Value := StateEdit.Text; MasterSQL.Active := True; DetailSQL.Active := True; end; Программа готова. Этот пример можно найти в директории Param. Синхронизация данных клиента и сервера. В ADO используются три метода синхронизации данных на клиенте и сервере.
Этих методы доступны во всех компонентах имеющих набор данных. Однако эти функции доступны не для всех баз данных. Работа с транзакциями В компонентах ADO работа с транзакциями осуществляется через компонентTADOConnection. Тип транзакции устанавливается в свойствеIsolationLevel одной из следующих констант:
Обратите внимание на то, что не все типы провайдеров данных поддерживают все типы изоляции или работу с транзакциями. Свойство Attributes устанавливает открывать ли новую транзакцию автоматически
Так же у компонента TADOConnection есть три метода для работы с транзакциями:
Пример работы с транзакциями За базовый возьмем пример использования TADOConnection. Добавим к форме две кнопки (StCmButton и RollbackButton) типа TButton, обработчики событий OnClick этих кнопок, процедуру fix_controls без параметров к форме, обработчик события OnActivate формы type TForm1 = class(TForm) … private procedure fix_controls; … procedure TForm1.fix_controls; begin if Connection.InTransaction then begin StCmButton.Caption := 'Commit'; RollbackButton.Enabled := True; end else begin StCmButton.Caption := 'Begin'; RollbackButton.Enabled := False; end; MasterSQL.Requery; DetailSQL.Requery; end; procedure TForm1.StCmButtonClick(Sender: TObject); begin if not Connection.InTransaction then Connection.BeginTrans else Connection.CommitTrans; fix_controls; end; procedure TForm1.RollbackButtonClick(Sender: TObject); begin Connection.RollbackTrans; fix_controls; end; procedure TForm1.FormActivate(Sender: TObject); begin fix_controls; end; Программу можно запускать. Этот пример находится в директории Trans. Обратите внимание на то, что когда транзакция не запущена, все равно можно изменять данные и они записываются немедленно . Доступ к данным В отличие от BDE, ADO поддерживает больше настроек работы данных. В ADO есть понятие набора данных (recordset) и тесно связанное с ним понятие курсора (cursor). Что такое курсор в документации на ADO не описано. Однако почему то месторасположение набора данных называется положением курсора. Я думаю, что это терминологическая путаница в Microsoft и курсор то же самое что набор данных. Во всех компонентах имеющих набор данных (то есть в TADODataSet, TADOTable, TADOQuery, TADOStoredProc) есть свойства CursorLocation, CursorType, LockType и MarshalOptions, устанавливающие параметры обмена с сервером. Все эти свойства должны быть установлены до того, как набор данных открывается. Если вы установите их позже, то эффекта не будет. CursorLocation - определяет, где выполняется работа с набором на клиенте (clUseClient) или на сервере (clUseServer). Если набор данных расположен на клиенте, то с сервера данные запрашиваются однократно (или до выполнения повторного запроса), в дальнейшем вся выборка данных и позиционирование идет на клиенте. Однако модификация данных производится немедленно. CursorType - устанавливает тип курсора. Значение одно из:
Надо заметить, что TDBGrid и другие компоненты, одновременно работающие с несколькими записями, могут работать только когда закладки поддерживаются. Поэтому для компонент с которыми вы будите связывать такие компоненты должны использоваться типы ctKeyset или ctDynamic. LockType - определяет тип блокировки записей в наборе данных. Оно из:
Работа с отложенными изменениями Обратите внимание, что в компонентах ADO нет свойства CachedUpdates, но это не означает, что невозможно отложить передачу изменений данных на сервер. Эта возможность встроена с ADO и называется Batch Updates. Для ее использования необходимо использовать клиентский курсор (то есть установить свойство CursorLocation в clUseClient) и LockType в ltBatchOptimistic Так же есть метод сохраняющий изменения UpdateBatch и метод их отменяющий CancelBatch. К каким записям из набора данных применяется действие зависит от единственного параметра этих функций arCurrent - текущая запись arFiltered - записи, которые попали в фильтрацию. arAll - все записи набора. Пример работы с отложенными изменениями.
procedure TForm1.FormActivate(Sender: TObject); begin fix_controls; ApplyButton.Visible := BatchCB.State = cbChecked; CancelButton.Visible := BatchCB.State = cbChecked; end; procedure TForm1.BatchCBClick(Sender: TObject); begin MasterSQL.Close; DetailSQL.Close; if BatchCB.State = cbChecked then begin MasterSQL.LockType := ltBatchOptimistic; DetailSQL.LockType := ltBatchOptimistic; end else begin MasterSQL.LockType := ltOptimistic; DetailSQL.LockType := ltOptimistic; end; MasterSQL.Open; DetailSQL.Open; ApplyButton.Visible := BatchCB.State = cbChecked; CancelButton.Visible := BatchCB.State = cbChecked; end; procedure TForm1.ApplyButtonClick(Sender: TObject); begin MasterSQL.UpdateBatch; DetailSQL.UpdateBatch; end; procedure TForm1.CancelButtonClick(Sender: TObject); begin MasterSQL.CancelBatch; MasterSQL.CancelBatch; end; События ADO События ADO предназначены для той же цели, что и события VCL. Многие из них имеют аналогичные события VCL и компоненты вызывают из событий ADO события VCL. В компонентах доступны как события ADO, так и события BDE. События соединения.
Эти события инкапсулированы в компоненте TADOConnection. События транзакции.
Эти события инкапсулированы в компоненте TADOConnection. События выполнения команд OnWillExecute и OnExecuteComplete вызываются перед и после выполнением команды. Эти события инкапсулированы в компоненте TADOConnection, а не в компоненте TADOCommand, как можно было бы предположить. Это связано с тем, что в ADO объекта команды как такого нет и по этой причине он не может получать сообщения. В TADOConnection также инкапсулировано событие OnInfoMessage, которое вызывается при приходе с сервера дополнительной информации. Формат и назначение зависят от сервера, с которым вы работаете. В ADO так же есть события связанные с набором данных, а не с соединением, как вышеописанные. Они инкапсулированы в компоненты имеющие набор данных - TADODataSet, TADOTable, TADOQuery и TADOStoredProc. Эти события можно разбить на три группы. 1) События выборки данных
2) Уведомления об изменении положения текущей записи в наборе.
3) Уведомления об изменении набора данных
Многие события допускают прерывание действия. Эта возможность бывает полезна при асинхронной работе с сервером. Например, для прерывания слишком длинного запроса. Асинхронная работа с сервером В ADO есть возможность не имеющая аналогов ни в BDE ни в InterBase. Это асинхронное выполнение операций с сервером. Могут асинхронно выполнятся установка соединения с сервером (Connection), выполнение команды (Execute) и выборка набора данных (Fetch) Асинхронное соединение Для включения этого режима необходимо установить свойство ConnectOptions компонента TADOConnection в coAsyncConnect. При установлении соединения происходит Вызывается обработчик события OnWillConnect Управление передается в программу После окончания соединения, как успешного, так и ошибочного, вызывается обработчик события OnConnectComplete Асинхронное выполнение команды Надо заметить, что все компоненты ADO, за исключением компонента TADOConnection при активизации или выполнении исполняют команду ADO. Этикомпоненты TADOCommand, TADODataSet, TADOTable, TADOQuery, TADOStoredProc. Установите в свойстве ExecuteOptionseoAsyncExecute. При исполнении происходит Вызывается обработчик события OnWillExecute Управление передается в программу После окончания выполнения команды, как успешного, так и ошибочного, вызывается обработчик события OnExecuteComplete Асинхронная выборка данных Асинхронная выборка данных поддерживается в компонентах TADODataSet, TADOTable, TADOQuery, TADOStoredProc. Для ее включения установите в свойстве ExecuteOptionseoAsyncFetch. После исполнения команды происходит передача данных. В процессе передачи многократно вызывается обработчик сообщения OnFetchProgress. В его параметрах есть как количество уже переданных записей, так и общее количество. Это очень удобно для создания индикаторов типа TProgressBar. После того, как выборка с сервера закончена, вызывается обработчик события OnFetchComplete. Ссылки по теме
|
|