1.背景
在B站学习某MFC课程时,由于自己的VS和MySQL的版本比较高,最终实现时废了好大的力气,记录了下,方便以后复习
2.准备工作
安装VS2019,能够创建MFC应用程序;
安装MySQL8或者其它版本;(注意安装时选择专业版,包含一些必要的驱动),如下图
3.首先创建数据源
参考连接,这个链接很详细的说明了ODBC数据源的创建
解决 win10 家庭版环境下 MySQL 的ODBC驱动下载及安装 - 我是小柒 - 博客园 (cnblogs.com)
第一步,找到控制面板-》系统和安全-》windows工具-》ODBC数据源
第二部,创建数据源
4.MFC向导创建完,缺少一个操作数据库的类,在VS2019中添加该类(我的是MyDataBaseSet,这个类是自定义的),这个类继承于CRecordset
参考链接
ODBC中如何利用CRecordset类对数据库进行操作 - 编程宝库 (codebaoku.com)
vs2019-MFC-ODBC使用者向导的手动实现_luooofan的博客-优快云博客
第一步:添加stdafx.h
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
#pragma once
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN // 从 Windows 头中排除极少使用的资料
#endif
#include "targetver.h"
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 某些 CString 构造函数将是显式的
// 关闭 MFC 对某些常见但经常可放心忽略的警告消息的隐藏
#define _AFX_ALL_WARNINGS
#include <afxwin.h> // MFC 核心组件和标准组件
#include <afxext.h> // MFC 扩展
#include <afxdisp.h> // MFC 自动化类
// 此处要求最小 DB 支持。 未选择任何视图。
#ifndef _AFX_NO_OLE_SUPPORT
#include <afxdtctl.h> // MFC 对 Internet Explorer 4 公共控件的支持
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC 对 Windows 公共控件的支持
#endif // _AFX_NO_AFXCMN_SUPPORT
#include <afxcontrolbars.h> // 功能区和控件条的 MFC 支持
#include <afxdb.h> // ODBC
#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif
第二步:添加stdafx.cpp
#include "pch.h"
#include "stdafx.h"
第三步:自定义ODBC接口类的头文件 MyDataBaseSet.h
// MyDataBaseSet.h: MyDataBaseSet 类的接口
//
#pragma once
#include<afxdb.h>//自己添加的文件,否则无法识别CRecordset类
// 代码生成在 2016年3月19日, 16:50
class MyDataBaseSet : public CRecordset
{
public:
MyDataBaseSet(CDatabase* pDatabase = NULL);
DECLARE_DYNAMIC(MyDataBaseSet)
// 字段/参数数据
// 以下字符串类型(如果存在)反映数据库字段(ANSI 数据类型的 CStringA 和 Unicode
// 数据类型的 CStringW)的实际数据类型。
// 这是为防止 ODBC 驱动程序执行可能
// 不必要的转换。如果希望,可以将这些成员更改为
// CString 类型,ODBC 驱动程序将执行所有必要的转换。
// (注意: 必须使用 3.5 版或更高版本的 ODBC 驱动程序
// 以同时支持 Unicode 和这些转换)。
long m_id;
CStringW m_name;
long m_age;
long m_score;
// 重写
// 向导生成的虚函数重写
public:
virtual CString GetDefaultConnect(); // 默认连接字符串
virtual CString GetDefaultSQL(); // 记录集的默认 SQL
virtual void DoFieldExchange(CFieldExchange* pFX); // RFX 支持
// 实现
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
};
第四步:定义ODBC接口类的cpp文件 , MyDataBaseSet.cpp
// MyDataBaseSet.cpp : MyDataBaseSet 类的实现
//
#include "pch.h"
#include "stdafx.h"
#include "MyDataBase.h" //包含项目名头文件
#include "MyDataBaseSet.h" //包含自己的ODBC接口类头文件
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// MyDataBaseSet 实现
// 代码生成在 2016年3月19日, 16:50
IMPLEMENT_DYNAMIC(MyDataBaseSet, CRecordset)
MyDataBaseSet::MyDataBaseSet(CDatabase* pdb)
: CRecordset(pdb)
{
//成员变量,分别对应学号,姓名,年龄,成绩
m_id = 0;
m_name = L"";
m_age = 0;
m_score = 0;
m_nFields = 4;//这个字段必须有,上面4个变量(m_id m_name m_agem_score),故写4
m_nDefaultType = snapshot; // 记录集默认类型
}
//#error 安全问题:连接字符串可能包含密码。
// 此连接字符串中可能包含明文密码和/或其他重要
// 信息。请在查看完此连接字符串并找到所有与安全
// 有关的问题后移除 #error。可能需要将此密码存
// 储为其他格式或使用其他的用户身份验证。
CString MyDataBaseSet::GetDefaultConnect()
{
//这个写自己创建的数据源名称,我上一步创建的是DataBaseTest_x64,故DSN=DataBaseTest_x64
return _T("DSN=DataBaseTest_x64");
}
CString MyDataBaseSet::GetDefaultSQL()
{
return _T("[user]");//表名,数据库表名
}
void MyDataBaseSet::DoFieldExchange(CFieldExchange* pFX)
{
pFX->SetFieldType(CFieldExchange::outputColumn);
// RFX_Text() 和 RFX_Int() 这类宏依赖的是
// 成员变量的类型,而不是数据库字段的类型。
// ODBC 尝试自动将列值转换为所请求的类型
//成员变量,分别对应学号,姓名,年龄,成绩
RFX_Long(pFX, _T("[id]"), m_id);
RFX_Text(pFX, _T("[name]"), m_name);
RFX_Long(pFX, _T("[age]"), m_age);
RFX_Long(pFX, _T("[score]"), m_score);
}
/
// MyDataBaseSet 诊断
#ifdef _DEBUG
void MyDataBaseSet::AssertValid() const
{
CRecordset::AssertValid();
}
void MyDataBaseSet::Dump(CDumpContext& dc) const
{
CRecordset::Dump(dc);
}
#endif //_DEBUG
MyDataBaseSet.cpp代码解释:(要改的地方)
CString MyDataBaseSet::GetDefaultConnect()
{
//这个写自己创建的数据源名称,我上一步创建的是DataBaseTest_x64
return _T("DSN=DataBaseTest_x64");
}
CString MyDataBaseSet::GetDefaultSQL()
{
return _T("[user]");//表名,数据库表名
}
注意
由于创建的数据源是x64位,故VS环境的配置也应该是x64位