Назад | Начало урока | Вперед
Содержание

Соединение с БД и получение данных

Все необходимое для соединения с БД и получения набора записей можно реализовать в функции OnNewDocument класса документа.

(АВ: Напомню эта функция в классе документа была создана автоматич в момент создания нами оболочки приложения типа Single Document и выбора CFormView в качестве базового класса нашего приложения. Мы наполним эту функцию новым содержанием. Эта очень важная функция в нашем приложении служит для соединения с БД и получения данных)

До того как реализовать эти возможности, следует добавить несколько переменных в класс документа:

- указатель m_ptrRs на объект RecordSet, (этим объектом является массив записей)
- указатель m_piAdoRecordBinding на интерфейс IADORecordBinding
и пару строковых переменных:
- строковую переменную m_strConnection для хранения строки соединения с БД
- строковую переменную m_strCmdText для команды SQL, выполнение которой необходимо для получения данных.

Добавьте эти переменные в класс документа;их свойства указаны в таб 13.23

Таб13.23 Переменные класса документа
Имя Тип Модификатор доступа
m_ptrRs _RecordsetPtr Private
m_piAdoRecordBinding IADORecordBinding* Private
m_strConnection CString Private
m_strCmdText CString Private

Функция OnNewDocument
Функция OnNewDocument выполняет ряд шагов для соединения с БД и получения набора записей.
  1. Во первых она устанавливает значение строки соединения с БД и строку, содержащую команду SQL.
  2. Затем она инициализирует среду модели компонентных объектов MicroSoft (COM) и два указателя так, что они содержат значения NULL.
  3. Для создания объекта RecordSet функция OnNewDocument вызывает функцию CreateInstance.Эта функция открывает объект RecordSet, устаналивает соединение с БД и запускает команду SQL.
  4. Затем она связывает экземпляр класса хранения данных с набором записей, используя указатель на интерфейс IADORecordBinding.
  5. И наконец эта функция дает указание экземпляру класса представления обновить введенные на экран данные и отобразить начальную запись, используя при этом функцию класса представления, который будет реализован позже.
Чтобы реализовать эту возможность измените функцию OnNewDocument класса документа добавив в нее код выделенный жирным:

Вверх

Листинг 13.4 Функция OnNewDocument()


BOOL CAdoDatabaseDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;

// (SDI documents will reuse this document)
// Установить строку соединения с БД и строку команды SQL
m_strConnection = _T("Provider=MSDASQL.1;Data Source=STYVCDB");
m_strCmdText = _T("select * from Addresses");

// Инициализировать нулем указатеь на набор(массив) данных и указатель на интерфейс IADORecordBinding
m_ptrRs = NULL;
m_piAdoRecordBinding = NULL;

// инициализировать среду модели компонентных объектов MicroSoft (COM)
::CoInitialize(NULL);
try
{

// создать набор (массив) объектов
m_ptrRs.CreateInstance(__uuidof(Recordset));

// открыть набор(массив) объектов
m_ptrRs->Open((LPCTSTR)m_strCmdText, (LPCTSTR)m_strConnection,

adOpenDynamic, adLockOptimistic, adCmdUnknown);

// получить указатель на интерфейс IADORecordBinding
if (FAILED(m_ptrRs->QueryInterface(__uuidof(IADORecordBinding),
(LPVOID *)&m_piAdoRecordBinding)))
_com_issue_error(E_NOINTERFACE);

// связать экземпляр класса записи m_rsRecSet с набором(массивом) записей
m_piAdoRecordBinding->BindToRecordset(&m_rsRecSet);

// получить указатель на вид
POSITION pos = GetFirstViewPosition();
CAdoDatabaseView* pView = (CAdoDatabaseView*)GetNextView(pos);
if (pView)
// вывести на экран значений полей записи
pView->RefreshBoundData();

}
// Any errors?
catch (_com_error &e)
{
// Display the error
GenerateError(e.Error(), e.Description());
}

return TRUE;

}


Анализ:

Функция OnNewDocument выполняет ряд шагов для соединения с БД и получения набора записей:

  1. Во первых она устанавливает значение строки соединения с БД .

    m_strConnection = _T("Provider=MSDASQL.1;Data Source=STYVCDB");

  2. Устанавливает строку, содержащую команду SQL

    m_strCmdText = _T("select * from Addresses");

  3. Затем она инициализирует среду модели компонентных объектов MicroSoft (COM) и два указателя так, что они содержат значения NULL.

    // Инициализировать объект Recordset и связанные с ним указатели
    m_ptrRs = NULL;
    m_piAdoRecordBinding = NULL;

    // Инициализировать среду COM(модели компонентных объектов)
    ::CoInitialize(NULL);
    try {

  4. Для создания объекта RecordSet функция OnNewDocument вызывает функцию CreateInstance.

    try {

    // создать объект Recordset (набор записей)
    m_ptrRs.CreateInstance(__uuidof(Recordset));

  5. Далее вызывается функция Open. Эта функция открывает объект RecordSet, устанвливает соединение с БД и запускает команду SQL.

    // открыть объект Recordset (набор записей)
    m_ptrRs->Open((LPCTSTR)m_strCmdText, (LPCTSTR)m_strConnection,

    adOpenDynamic, adLockOptimistic, adCmdUnknown);

  6. Далее запускается функция QueryInterface позволяющая получить указатель m_piAdoRecordBinding на интерфейс IADORecordBinding. Этот указатель используется для обмена данными.

    // получить указатель на интерфейс IADORecordBinding , используемый для обмена данными
    if (FAILED(m_ptrRs->QueryInterface(__uuidof(IADORecordBinding),

    (LPVOID *)&m_piAdoRecordBinding)))
    _com_issue_error(E_NOINTERFACE);

  7. Затем она связывает экземпляр класса хранения данных m_rsRecSet с набором(массивом) записей, используя указатель m_piAdoRecordBinding на интерфейс IADORecordBinding.

    // связать экземпляр класса хранения данных с набором записей
    m_piAdoRecordBinding->BindToRecordset(&m_rsRecSet);

  8. И наконец эта функция дает указание экземпляру класса представления обновить введенные на экран данные и отобразить начальную запись, используя при этом функцию класса представления, который будет реализован позже.

    // получить указатель на представление
    POSITION pos = GetFirstViewPosition();
    CAdoDatabaseView* pView = (CAdoDatabaseView*)GetNextView(pos);

    if (pView)
    // Синхронизировать набор данных с формой
    pView->RefreshBoundData();

АВ:
Характерная последовательность вызова функций для связи класса документа с классом вида:

pos = GetFirstViewPosition();
pView = GetNextView(pos);
pView->RefreshBoundData();

АВ:Полагаю что после вызова рассмотренной здесь функции OnNewDocument() все поля выведенной на экран записи будут чистыми (не заполненными). Ведь это будет новый набор записей, не так ли? Нет! Все поля созданной нами формы приложения будут заполнены данными из первоначальной записи БД. А мы предположили, и на практике так сделали, что наша база данных уже инициализирована (заполнена) данными.


АВ:Вопрос:
Функциями какого класса являются использованные здесь функции для получения указателя не вид
GetFirstViewPosition() и GetNextView(pos)?

Ответ:
Функции для получения указателя на вид едва ли могут находиться внутри класса вида!?Значит это функции какого то другого класса.Какого?

Это функции класса CDocument - родительского класса документа CAdoDatabaseDoc :

virtual POSITION GetFirstViewPosition() const;
virtual CView* GetNextView(POSITION& rPosition) const;

Ну это же очевидно! Функции еще какого же класса можно так запросто вызывать? Конечно, функции родительского класса.


В вышерассмотренном листинге 13.4 определяется что для связи с БД Access будет использоваться драйвер доступа MSDASQL.Это драйвер доступа ODBC, разработанный специально для технологии OLE для баз данных (OLE DB) и являющийся частью ADO.

m_strConnection = _T("Provider=MSDASQL.1;Data Source=STYVCDB");

Если вы намерены работать с БД SQL Server 2000, вам следует использовать драйвер доступа SQLOLEDB.
Информацию о драйверах доступа для других БД можно найти в документации по этим базам.

Функция DeleteContents
Прежде чем мы продолжим, убедитесь что в приложение добавлен весь необходимый для корректного завершения приложения код. Приложение должно закрыть набор записей и освободить указатель на интерфейс, используемый для обмена данными. Кроме того следует очистить среду (COM). Чтобы добавить эту возможность выполните следующее:

  1. Добавьте перегруженную функцию DeleteContents в класс документа так, как это делалось в нескольких предыдущих главах. (АВ: Почему перегруженную? Потому, что одноименная функция есть в родительском классе CDocument)
  2. Отредактируйте функцию как в 13.5

Вверх

Листинг 13.5 Функция DeleteContents()


void CAdoDatabaseDoc::DeleteContents()
{
// Закрыть набор записей
if (m_ptrRs)
m_ptrRs->Close();

// Мы имеем допустимый указатель на Интерфейс IAdoRecordBinding?
if (m_piAdoRecordBinding)

// освободить его
m_piAdoRecordBinding->Release();

// Обнулить указатель
m_ptrRs = NULL;

// Закрыть среду модели COM-объектов
CoUninitialize();
CDocument::DeleteContents();

}

АВ: Разумеется функция, которая корректно закрывает все ранее установленные связи с БД необходима!


Назад | Начало урока | Вверх | Вперед
Содержание

Hosted by uCoz