MFC与ODBC(笔记)

        ODBC:为客户编程软件提供了一种统一的接口。可用于处理不同数据库的客户应用程序。使用ODBC的应用程序可以与任何具有ODBC驱动程序的数据库进行通信。

        DAO:数据库访问对象,是一组数据库引擎的COM自动化接口。不是ODBC那样面向C++程序员,而是提供给VisualBasic开发人员的一种简单的数据库访问方法,用于操纵Access数据库。

        RDO:远程数据对象。通过直接调用ODBC API,可以为使用关系数据库的应用程序提供更好的性能。

一、准备工作

创建MFC文件,选择以下格式

此处有些版本的MFC是没有支持数据的部分,因此需要自己设置。

笔者使用的为MySQL数据库。


数据源:用来记录连接数据库的信息,在创建数据库连接时需要,之后使用中不再需要。一个数据库可以有多个数据源连接。

它可分为文件数据源和机器数据源。

  • 文件数据源:可以拷贝给其他计算机用
  • 机器数据源:只有本机可以使用。机器数据源又分为:
    • 用户数据源:当前创建的用户可见
    • 系统数据源:所有用户可见

它的更新模式分为快照和动态记录集两种。

  • 快照记录集:每次操作重新查询后才更新
  • 动态记录集:每次操作自动更新(添加记录除外)

笔者的版本没有数据源。因此直接手动导入数据库用的是Mysql自带的包,注意,需要去Oracle官网下载ODBC管理程序。因为MFC的CDatabase需要数据源格式文件。

并建立如下数据库。

 现在打开ODBC管理程序。

注意不要开启错了

通过“控制面板”进入“管理工具”

 打开64位的(所含内容不同)

 现在在文档DSN标签下,添加文档DSN(数据源),并完成配置。如此便生成完毕。

二、MFCApplication1Set类

现为MFC新增一类,还原MFC同ODBC自动生成的结构。

命名方式为MFCApplication1Set.h与.cpp

在完成下列代码后,其实数据源便没用了。其主要作用就是辅助生成连接数据库的基本代码。

#pragma once
#include "afxdb.h"
class CMFCApplication1Set : public CRecordset {
public:
	CMFCApplication1Set(CDatabase* pDatabase = NULL);
	DECLARE_DYNAMIC(CMFCApplication1Set);
public:
	//此处是我们的数据库字段/参数数据
	int m_sno;
	CString m_address;
	CString m_sname;
// 重写
// 向导生成的虚函数重写
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
};
#include "pch.h"
#include "MFCApplication1Set.h"

IMPLEMENT_DYNAMIC(CMFCApplication1Set, CRecordset)

CMFCApplication1Set::CMFCApplication1Set(CDatabase* pDatabase)
:CRecordset(pDatabase)
{
	m_sno = 0;
	m_sname = L"";
	m_address = L"";
	m_nFields = 3;//数据域数目
	m_nDefaultType = snapshot;//快照模式
}
#ifdef _DEBUG
void CMFCApplication1Set::AssertValid() const
{
	CRecordset::AssertValid();
}

void CMFCApplication1Set::Dump(CDumpContext& dc) const
{
	CRecordset::Dump(dc);
}

#endif //_DEBUG

void CMFCApplication1Set::DoFieldExchange(CFieldExchange* pFX)
{
	pFX->SetFieldType(CFieldExchange::outputColumn);
	RFX_Int(pFX, _T("[sno]"), m_sno);
	RFX_Text(pFX, _T("[sname]"), m_sname);
	RFX_Text(pFX, _T("[address]"), m_address);
}


CString CMFCApplication1Set::GetDefaultConnect()
{
//数据源中信息
	return _T("Driver=MySQL ODBC 8.0 Unicode Driver;SERVER=127.0.0.1;UID=用户;PWD=密码;DATABASE=数据库名;PORT=端口号(3360)");
}

CString CMFCApplication1Set::GetDefaultSQL()
{
	return _T("[students]");
}

三、窗口布局

建立如下布局

 为编辑框右击添加值变量

 自动生成如下代码:

 同时要初始化m_sno

四、数据库类

DOC类的头文件中添加CMFCApplication1Set的头文件,而后添加成员变量以及方法。

// 特性
public:
	CMFCApplication1Set* GetSet() {
			return &pSet;
	}
private:
	CMFCApplication1Set pSet;//数据库记录集对象

 然后在View的中修改如下

void CMFCApplication1View::OnInitialUpdate()
{
	CFormView::OnInitialUpdate();
	GetParentFrame()->RecalcLayout();
	ResizeParentToFit();

	//初始化时,把数据库打开
	//文档对象指针
	CMFCApplication1Doc* pDoc = GetDocument();
	//数据库记录集指针
	pSet = pDoc->GetSet();
	if (pSet->IsOpen() == FALSE) {//数据库未开启,则打开
		pSet->Open();
	}
	if (pSet->IsEOF()) {
		m_sno = 0;
	}
	else {
		//初始化内容
		pSet->MoveFirst();
		m_sno = pSet->m_sno;
		m_sname = pSet->m_sname;
		m_address = pSet->m_address;
	}
	UpdateData(FALSE);
}

 五、添加事件

 为“上一个”、“下一个”添加点击事件

(pSet->requery()可以重置查询)

//上一个
void CMFCApplication1View::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	if (pSet->IsEOF()) {
		return;
	}
	pSet->MovePrev();
	//如果是开始的第一个
	if (pSet->IsBOF()) {
		//变为最后一个	
		pSet->MoveLast();
	}
	m_sno = pSet->m_sno;
	m_sname = pSet->m_sname;
	m_address = pSet->m_address;
	UpdateData(FALSE);
}

//下一个
void CMFCApplication1View::OnBnClickedButton2()
{
	// TODO: 在此添加控件通知处理程序代码
	if (pSet->IsEOF()) {
		return;
	}
	pSet->MoveNext();
	if (pSet->IsEOF()) {
		pSet->MoveFirst();
	}
	m_sno = pSet->m_sno;
	m_sname = pSet->m_sname;
	m_address = pSet->m_address;
	UpdateData(FALSE);
}

 为“添加记录”以及“确认”按钮添加点击事件

//添加记录
void CMFCApplication1View::OnBnClickedButton3()
{
	// TODO: 在此添加控件通知处理程序代码
	//数据库添加空记录
	pSet->AddNew();

}

//确定添加记录
void CMFCApplication1View::OnBnClickedButton7()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData(TRUE);
	pSet->m_sno =m_sno;
	pSet->m_sname = m_sname;
	pSet->m_address = m_address;
	//更新到数据库
	if (pSet->CanUpdate()) {
		pSet->Update();
	}
}

 为“修改”按钮添加点击事件

//修改
void CMFCApplication1View::OnBnClickedButton4()
{
	// TODO: 在此添加控件通知处理程序代码
	pSet->Edit();
	UpdateData(TRUE);
	pSet->m_sno = m_sno;
	pSet->m_sname = m_sname;
	pSet->m_address = m_address;
	//更新到数据库
	if (pSet->CanUpdate()) {
		pSet->Update();
	}
}

为”删除“按钮添加点击事件

//删除
void CMFCApplication1View::OnBnClickedButton5()
{
	// TODO: 在此添加控件通知处理程序代码
	//删除
	pSet->Delete();
	//重新查询
	pSet->Requery();
	if (pSet->IsEOF()) {
		m_sno = 0;
		m_sname.Empty();
		m_address.Empty();
	}
	else {
		m_sno = pSet->m_sno;
		m_sname = pSet->m_sname;
		m_address = pSet->m_address;
	}
	UpdateData(FALSE);
}

为”学号大于3“按钮添加 点击事件

//查询
void CMFCApplication1View::OnBnClickedButton8()
{
	// TODO: 在此添加控件通知处理程序代码
	pSet->m_strFilter = TEXT("sno > 3");
	pSet->Requery();
	if (pSet->IsEOF()) {
		m_sno = 0;
		m_sname.Empty();
		m_address.Empty();
	}
	else {
		m_sno = pSet->m_sno;
		m_sname = pSet->m_sname;
		m_address = pSet->m_address;
	}
	UpdateData(FALSE);
}

为”学号降序“按钮添加点击事件

void CMFCApplication1View::OnBnClickedButton6()
{
	// TODO: 在此添加控件通知处理程序代码

	//默认升序
	pSet->m_strSort = TEXT("sno desc");
	pSet->Requery();
	if (pSet->IsEOF()) {
		m_sno = 0;
		m_sname.Empty();
		m_address.Empty();
	}
	else {
		m_sno = pSet->m_sno;
		m_sname = pSet->m_sname;
		m_address = pSet->m_address;
	}
	UpdateData(FALSE);
}

为”取消条件“按钮添加点击事件

//取消条件
void CMFCApplication1View::OnBnClickedButton9()
{
	// TODO: 在此添加控件通知处理程序代码
	pSet->m_strFilter = TEXT("");
	pSet->m_strSort = TEXT("");
	pSet->Requery();
	if (pSet->IsEOF()) {
		m_sno = 0;
		m_sname.Empty();
		m_address.Empty();
	}
	else {
		m_sno = pSet->m_sno;
		m_sname = pSet->m_sname;
		m_address = pSet->m_address;
	}
	UpdateData(FALSE);
}

结果: 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值