Среда программирования Visual C++. Создание приложения, работающего с базой данных, средствами мастера AppWizard

   
На этом шаге мы рассмотрим алгоритм создания приложения, использующего базу данных.

   
Чтобы получить наглядное представление о взаимодействии классов базы данных, набора записей и представления
данных, создадим приложение для работы с базой данных средствами мастера AppWizard. Оно будет основано
на формах и предназначено для выборки и изменения данных базы pubs на SQL Server через
ODBC-источник данных, созданный на 119 шаге. Хотя во всех дальнейших
примерах применяются ODBC-классы, демонстрируемые методы работают и для DAO-классов.

  • Создание приложения MyDBApp.
  • В меню File выберите пункт New и создайте проект MFC AppWizard (ехе), назвав его MyDBApp.
  • В окне 1 мастера AppWizard выберите Single document и щелкните Next, чтобы перейти к окну 2 (рисунок 1).
    Рис.1. Варианты поддержки баз данных в AppWizard

       
    В окне 2 Вам предлагается указать один из четырех возможных вариантов поддержки БД в Вашем приложении. Выбрав
    первый вариант, Вы откажетесь от такой поддержки. Второй вариант позволяет включить в проект заголовочные файлы БД,
    в результате чего Вы сможете применять классы базы данных и вручную создавать собственные наборы записей.
    Третий и четвертый варианты предназначены для конструирования полноценного приложен архитектуры "документ/вид",
    в котором класс документа содержит набор записей, а класс вида является производным от CRecordView или
    CDaoRecordView. В третьем варианте не поддерживается сериализация, и поэтому его обычно применяют для
    простых приложений на базе форм, предназначенных для просмотра и/или модификации данных в БД. Выбирайте
    четвертый вариант, если Вам требуется поддержка сериализации.

  • Щелкните Database view without file support. Поскольку Вы будете просматривать базу данных, то нужно выбрать источник данных
    для созданного в проекте класса набора записей. Щелкните Data Source. Откроется диалоговое окно Database Options (рисунок 2).


    Рис.2. Диалоговое окно Database Options

  • Убедитесь, что выбран пункт ODBC. Откройте список зарегистрированных источников данных и выберите MyDSN.
  • Убедитесь, что указан тип набора записей Snapshot, и щелкните ОК. Имейте в виду, что при этом
    должны быть доступны службы SQL Server, иначе выполнить операцию Вам не удастся. В результате будет открыто диалоговое окно Select Database Tables.
  • Щелкните dbo.authors и затем - OK (dbo - это имя владельца, присвоенное таблице SQL Server).
    Рис.3. Окно Select Database Tables
  • Щелкайте Finish во всех остальных окнах AppWizard, чтобы принять значения по умолчанию. Завершите процесс создания
    пректа, щелкнув ОК в диалоговом окне New Project Information.

   
После этого в редакторе диалогов откроется шаблон диалога IDD_MYDBAPP_FORM, на котором основан
класс представления записей CMyDBAppView. Это напоминание Вам о том, что прежде чем отображать в представлении
какие-либо данные, Вы должны создать элементы управления.

   
До создания шаблона диалога просмотрите сгенерированный мастером AppWizard код, чтобы понять, как
реализуется приложение с поддержкой БД.

  • Просмотр кода, сгенерированного AppWizard.
  • Откройте файл MyDBAppSet.h и взгляните на определение класса набора записей. Обратите внимание, что AppWizard добавил в него
    группу переменных-членов RFX - по одной на каждый столбец таблицы авторов.
  • Откройте файл MyDBAppSet.cpp и найдите функцию CMyDBAppSet::DoFieldExchange(). Обратите
    внимание, что она похожа на DDX-функцию DoDataExchange(). Для каждого столбца таблицы авторов AppWizard
    добавляет вызов соответствующей RFX-функции.
  • Функция-член GetDefaultSQL(), расположенная перед функцией DoFieldExchange(), задает выражение
    FROM оператора SELECT, который, собственно, и создает набор записей:

    CString CMyDBAppSet::GetDefaultSQL()
    {
    	return _T("[dbo].[authors]");
    }
    

       
    Обратите внимание, что по умолчанию в сгенерированном коде имена ODBC-объектов заключаются в квадратные скобки, хотя это требуется,
    только когда они содержат пробелы. Чтобы задать фильтр для набора записей, задайте строку с выражением WHERE в переменной-члене
    m_strFilter Вашего класса набора записей. Кроме того, указав строку с выражением ORDER BY в переменной-члене m_strSort,
    Вы отсортируете данные требуемым образом.

  • Функция-член GetDefaultConnect(), расположенная перед функцией GetDefaultSQL(), возвращает строку подключения, в
    которой задан источник данных для Вашего набора записей.

    CString CMyDBAppSet::GetDefaultConnect()
    {
    	return _T("ODBC;DSN=MyDSN");
    }
    

       
    Каркас не создает для Вашего проекта объект, производный от СDatabase. Вместо этого конструктору объекта набора записей
    передается параметр NULL, что приводит к созданию временного объекта CDatabase.

       
    Если для доступа к источнику данных требуется авторизация SQL Server, Вы можете предотвратить вывод диалогового окна SQL Server Login
    во время выполнения приложения, создав такую строку подключения:
    CString CMyDBAppSet::GetDefaultConnect()

    {
           return _T("ODBC; DSN=MyDSN; UID=sa; PWD="); 
    }
    

       
    Здесь предполагается, что для учетной записи sa пароль не задан

  • И наконец, открыв файл MyDBAppDoc.h, просмотрите определение класса документа. Обратите внимание, что в классе
    СМуDBAppDoc есть переменная-член m_myDBAppSet. Приложение CMyDBApp полностью соответствует
    архитектуре "документ/вид" - класс документа содержит данные приложения, отображаемые классом представления
    (CMyDBAppView).

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

  • Удаление лишних полей из класса набора записей.
  • Нажмите CTRL+W, чтобы открыть ClassWizard, и щелкните вкладку Member Variables.
  • Выберите класс CMyDBAppSet. В списке переменных-членов щелкните m_au_id, соответствующую столбцу [au_id], и затем -
    Delete Variable.
  • Точно так же удалите переменную m_contract, соответствующую столбцу [contract]. Щелкните ОК, чтобы сохранить изменения.


Рис.4. Результат удаления переменных

   
Теперь вернитесь к шаблону диалога IDD_MYDBAPP_FORM и создайте элементы управления для отображения данных, хранящих в переменных набора записей.

  • Изменение шаблона диалога представления записей.
  • В редакторе диалогов добавьте в шаблон диалога IDD_MYDBAPP_FORM три статических текстовых строки и семь полей ввода,
    как показано на рисунке 5.


    Рис.5. Шаблон диалога IDD_MYDBAPP_FORM

  • Полям ввода присвойте следующие идентификаторы:
    • IDC_AU_FNAME;
    • IDC_AU_LNAME;
    • IDC_AU_ADDRESS;
    • IDC_AU_CITY;
    • IDC_AU_STATE;
    • IDC_AU_ZIP;
    • IDC_AU_PHONE.

   
Далее средствами мастера ClassWizard Вы свяжете их с переменными-членами класса набора записей.

  • Связывание переменных класса набора записей с идентификаторами элементов управления диалога представления записей.
  • На вкладке Member Variables выберите класс CMyDBAppView.
  • В поле Control IDs щелкните IDC_AU_ADDRESS и затем - Add Variable.
  • Раскройте список Member variable name и просмотрите все члены-данные класса, которые можно связать с элементами
    управления в представлении записей. Выберите переменную m_pSet->m_address.


    Рис.6. Связывание IDC_AU_ADDRESS с m_pSet->m_address

  • Убедитесь, что в поле Category указано значение Value, а в поле Variable - CString, и щелкните ОК.
  • Таким же образом свяжите остальные идентификаторы элементов управления с соответствующими переменными класса набора записей.
    Для IDC_AU_STATE задайте ограничение на ввод не более двух символов.


    Рис.7. Результат связывания

  • Щелкните ОК, чтобы закрыть ClassWizard и сохранить все изменения.

   
Откройте файлы MyDBAppView.h и MyDBAppView.cpp и посмотрите на изменения, внесенные
ClassWizard. Обратите внимание, что в классе CMyDBAppView не появилось никаких новых переменных-членов - просто созданы связи
между элементами управления и существующими переменными класса CMyDBAppSet. Это связывание
реализуется мастером ClassWizard путем вызова функции DDX_FieldText() из функции представления
записей DoDataExchange(). Вот как это выглядит:

void CMyDBAppView::DoDataExchange(CDataExchange* pDX)
{
	CRecordView::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CMyDBAppView)
	DDX_FieldText(pDX, IDC_AU_ADDRESS, m_pSet->m_address, m_pSet);
	DDX_FieldText(pDX, IDC_AU_CITY, m_pSet->m_city, m_pSet);
	DDX_FieldText(pDX, IDC_AU_FNAME, m_pSet->m_au_fname, m_pSet);
	DDX_FieldText(pDX, IDC_AU_LNAME, m_pSet->m_au_lname, m_pSet);
	DDX_FieldText(pDX, IDC_AU_PHONE, m_pSet->m_phone, m_pSet);
	DDX_FieldText(pDX, IDC_AU_STATE, m_pSet->m_state, m_pSet);
	DDV_MaxChars(pDX, m_pSet->m_state, 2);
	DDX_FieldText(pDX, IDC_AU_ZIP, m_pSet->m_zip, m_pSet);
	//}}AFX_DATA_MAP
}

   
Имейте в виду, что можно также прибегнуть к стандартной DDV-функции проверки.

   
Соберите и запустите приложение MyDBApp. Оно должно выглядеть, как показано на рисунке 8.


Рис.8. Приложение MyDBApp

   
Обратите внимание, что класс CRecordView предоставляет панель передвижения по набору записей с кнопками
вперед, назад, перемещение в начало и в конец. Каркас связывает идентификаторы элементов управления этих кнопок с
функцией представления записей OnMove(). В базовом классе при переходе к другой записи эта функция вызывает
CWnd::UpdateData(TRUE) для сохранения изменений текущей записи и CWnd::UpdateData(FALSE) - для
отображения другой записи из набора. UpdateData обновляет представление, вызывая DoDataExchange().

   
Текст этого приложения можно взять здесь (41,7 Кб).

   
На следующем шаге мы рассмотрим задание фильтров в наборах записей.



Вы можете оставить комментарий, или Трекбэк с вашего сайта.

Оставить комментарий