Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции ОТИ - копия.doc
Скачиваний:
3
Добавлен:
01.07.2025
Размер:
8.91 Mб
Скачать

Упражнение 4. Связывание отдельных частей

Контрольные вопросы:

  1. Перечислите основные шаги создания ODBC-приложения с помощью AppWizard.

  2. Какой класс становится базовым для класса представления в создаваемом приложении?

  3. Расскажите о механизме связывания элементов управления с переменными создаваемого класса при использовании класса CRecordView.

Занятие №33

Лабораторная работа №11 «Реализация основных функций работы с БД с помощью ClassWizard»

Цель: редактирование приложения баз данных типа с использованием инструментальных средств Visual C++, исследование средства доступа ODBC к базам данных.

Упражнение 1 Добавление кода в проект MyFirst.

Упражнение 2. Добавление фильтра записей.

Упражнение 3. Добавление и удаление записей.

Контрольные вопросы:

  1. Как использовать переменные m_strFilter и m_strSort для фильтрации и сортировки полей?

  2. Какой вариант осуществления фильтрации вам ещё известен? Как он работает?

  3. Как добавлять и удалять записи в приложении?

Занятие №34

Средства доступа к базам данных.

Использование DAO

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

С другой стороны, упомянутая гибкость требует жертв. Если используемая база данных обладает специальными возможностями, то получить к ним доступ через драйвер ODBC нельзя. И даже если это удастся, то, прежде всего, потеряется мобильность, присущая применению ODBC. Кроме того, доступ через ODBC к базам данных типа FoxPro и Access оказывается не настолько быстрым, как прямое подключение к собственно механизму упомянутых баз данных. Такие задачи позволят решать объекты доступа к данным — Microsoft Data Access Objects (DAO).

В DAO можно напрямую использовать механизм базы данных Access (Jet) для чтения и записи. Кроме того, механизм Jet позволяет напрямую читать и записывать большое множество файлов данных настольных ПК, таких как FoxPro и dBASE. Этот механизм можно использовать даже для подключения к удаленным источникам данных ODBC, котя последнее несколько неэффективно.

Помимо своей эффективности, DAO обладает еще рядом преимуществ по сравнению с ODBС. Классы DAO в целом более мощны. Вы можете без труда отыскать в наборе записей конкретное значение, либо запомнить своё текущее местонахождение, разместив закладку. Кроме этого, можно воспользоваться командами Data Definition Language (DDL — язык объявления данных) для добавления таблиц, а также изменения структуры базы данных. В конце концов, DAO предоставляет объектно-ориентированный интерфейс, который особенно хорошо подходит для C++.

Создание приложения CDaoRecordView

Структура приложения MFC с архитектурой "документ-представление" подобна той, которая использовалась для классов ODBC. Изменилось лишь несколько имен классов. Например, приложение вместо CRecordView использует CDaoRecordView. Вместо указателя на объект CRecordSet работа осуществляется с указателем на объект CDaoRecordSet. Кроме отличающихся имен классов внесено мало изменений — имена переменных класса и способ, в соответствие с которым ClassWizard общается с полями данных, остались прежними. Если не обратить внимание на различия в именах классов, то можно вообще не заметить никакой разницы — по меньшей мере, до тех пор, пока не придется использовать CDaoRecordSet. Затем следует обратить внимание на присутствие дополнительных функций, подобных FindFirst() and Seek().

Чтобы ощутить особенности работы с классом CDaoRecordView, давайте построим другое простое приложение для просмотра таблиц. В нем будет использована любая таблица той же базы данных POSTAVKA.mdb, что и в предыдущих примерах.

Выполним следующие шаги:

  1. Создадим новый проект AppWizard MFC и назовём его MySecond. Создадим SDI-приложение с поддержкой архитектуры "документ-представление". В диалоговом окне MFC AppWizard — Step 2 выберем Database Without File Support. Нажмём на Data Source, чтобы вывести диалоговое окно Database Options. Выберём переключатель DAO, а в секции Recordset Туре выберите Table. DAO позволяет напрямую работать с таблицами, чего не было в ODBC. Нажмём на кнопку с троеточием, выберём требуемую базу данных и щелкнём на ОК.

  2. Откроется список таблиц базы данных. (Если в качестве источника записей выбран Dynaset или Snapshot, в списке будут присутствовать также и залросы к базе данных.) Выберем нужную таблицу, и нажмём на ОК.

Рис. 34.1. Заполнение диалогового окна Database Options для приложения

  1. На остальных шагах AppWizard примем значения, предлагаемые но умолчанию. Заметьте, что вместо класса CRecordView приложение основывается на CDaoRecordView. Когда AppWizard завершит создание файлов для приложения, откроем ClassWizard и посмотрим на поля, сгенерированные для класса CMySecondSet. AppWizard создает поле для каждой колонки базы данных.

  2. Откроем диалоговое окно главной формы в Dialog Editor, удалим элемент статического текста To Do и разместим на форме 7 панелей статического текста и 7 элементов редактирования. Назовём их IDC_KOD_TOV, IDC_TOVAR и т.д. Установим заголовки элементов статического текста. Разместим эти компоненты и воспользуемся командой меню Layout | Tab Order, чтобы установить их порядок обхода.

  3. С помощью ClassWizard свяжем каждый элемент управления с одной из внешних переменных класса CMySecondSet. В диалоговом окне Add Member Variable используем выпадающий список для выбора имени каждой внешней переменной. Установим длину полей.

  4. Откомпилируем и запустим программу. Можно, как и ранее, передвигаться по базе данных и изменять элементы данных – и всё это без написания какого-либо кода. Как и прежде, можно внести некоторые улучшения. На этот раз мы оставим в покое фильтрование и сортировку, а поработаем над Add и Delete.

Улучшение MySecond

Улучшение проекта начинается с изменения идентификатора поставщика с “чтения-записи” на “только для чтения”. Для этого не нужно добавлять код – просто откроем форму в Dialog Editor и отметим флажок свойства Read-Only для поля IDC_KOD_TOV

Вместо использования меню давайте на этот раз соединим команды Add и Delete с кнопками панели инструментов. Выполним следующие шаги:

  1. Откроем ресурс панели инструментов IDR_MAINFRAME в редакторе панели инструментов (Toolbar Editor).

  2. Удалим с панели инструментов кнопки Cut, Copy, Paste и Print. Помним, что удаление кнопок с панели инструментов осуществляется простым перетаскиванием их за пределы панели инструментов.

  3. Добавим в панель инструментов две новых кнопки, расположив их слева от кнопок со стрелками для движения по таблице. На первой кнопке нарисуем контур листа бумаги. На второй нарисуем небольшую мусорную урну. Установим идентификаторы ресурсов, соответственно, в ID_ADD_NEW и ID_DELETE. Снабдим каждую кнопку соответствующей подсказкой.

  4. Добавим в класс CMySecondView новую переменную bool m_IsAdding. Используем ClassWizard для создания обработчика COMMAND для ID_ADD_NEW и ID_DELETE. Поместим выделенный код из листинга 34.1 в функцию, сгенерированную AppWizard.

Листинг 34.1. Функции OnAddNew() and OnDelete()

Void CMySecondView::OnAddNew()

{

m_pSet->MoveLast();

long newID=m_pSet->m_ +1;

m_pSet->AddNew();

m_pSet->SetFieldNull(&(m_pSet->m_KOD_TOV),FALSE);

m_pSet-> m_KOD_TOV = newID;

UpdateData(FALSE);

m_IsAdding=true;

}

Void CMySecondView::OnDelete()

{

m_pSet->Delete();

m_pSet->MoveNext();

if (m_pSet->IsEOF())

m_pSet->MoveLast();

UpdateData(FALSE);

}

Добавление и удаление в MySecond

Как и в приложении MyFirst, для добавления новых записей в базу данных используем модальное диалоговое окно. Когда пользователь нажимает Add New, программа переходит на последнюю запись в файле, извлекает значение идентификатора KOD_TOV в качестве ключа для следующей записи, после чего вызывает AddNew(). Чтобы пользователь не вводил новый идентификатор KOD_TOV, мы вычислим новое значение и сохраним его в поле m_KOD_TOV. Обратите внимание на то, как функция SetFieldNull() предотвращает установку пустого значения в поле KOD_TOV.

После установки ключевого поля OnAddNew() установит поле m_IsAdding в true и завершит выполнение. Функция OnMove(), которая вызывает функцию CDaoRecordSet::Update(), сохраняет значения в базе данных.

В отличие от MyFirst-версии Delete, функция MySecondView::OnDelete() предоставляет системе возможность распоряжаться исключениями; она просто удаляет текущую запись, а затем вызывает MoveNext().