【MFC】数据库操作——ODBC(20)

ODBC:开放式数据库连接,是为解决异构数据库(不同数据库采用的数据存储方法不同)共享而产生的。ODBC API相对来说非常复杂,这里介绍MFC的ODBC类。

添加ODBC用户DSN

首先,在计算机中添加用户DSN:(WIN10下,搜索ODBC)

 点添加,以SQL Server为例,其他类似(MYSQL需要安装对应的ODBC驱动):

 填写DSN名称、描述,IP地址(本机用127.0.0.1)

 本机用windows用户登录,其他电脑可以使用用户名+密码登录:

 选择对应的数据库(要注意!)

 点完成后,测试一下数据源:

在ODBC中出现用户DSN,表明添加成功。

使用MFC ODBC类

创建工程-》单文档-》在数据库支持步,选择数据库:

 点击数据源,选择上面添加的test :

 点确定后,选择数据库中的表格(只能选择一张表):

 点确定后,创建完工程,打开资源视图,在主视图中添加一些控件,用于显示数据库中数据:

 注意控件与数据库中表格进行对应:(示例中显示数据库表中的四列)

修改视图代码,直接完成控件与数据库列的绑定:

在视图类中响应工具栏中的四个命令:

 代码如下:

 运行程序即可以看到数据库中数据(有一个安全警告,删除代码即可)

添加排序、搜索功能:

通过设置RecordSet的排序字段 m_strSort  重新查询数据库即可以完成按该关键字排序

通过设置RecordSet的排序字段 m_strFilter 则可以根据该字段对数据库进行搜索(其实就是where子句)

代码如下:

视图头文件:


// MFC10View.h : CMFC10View 类的接口
//

#pragma once

class CMFC10Set;

class CMFC10View : public CRecordView
{
protected: // 仅从序列化创建
	CMFC10View();
	DECLARE_DYNCREATE(CMFC10View)

public:
	enum{ IDD = IDD_MFC10_FORM };
	CMFC10Set* m_pSet;

// 特性
public:
	CMFC10Doc* GetDocument() const;

// 操作
public:

// 重写
public:
	virtual CRecordset* OnGetRecordset();
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
	virtual void OnInitialUpdate(); // 构造后第一次调用
	virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
	virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
	virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

// 实现
public:
	virtual ~CMFC10View();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// 生成的消息映射函数
protected:
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnRecordFirst();
	afx_msg void OnRecordLast();
	afx_msg void OnRecordNext();
	afx_msg void OnRecordPrev();
	afx_msg void OnBnClickedButton1();
	afx_msg void OnClickedTagnames();
	CString m_strSel;
	CString m_filter;
	void Query();
	afx_msg void OnBnClickedButton2();
};

#ifndef _DEBUG  // MFC10View.cpp 中的调试版本
inline CMFC10Doc* CMFC10View::GetDocument() const
   { return reinterpret_cast<CMFC10Doc*>(m_pDocument); }
#endif

CPP文件


// MFC10View.cpp : CMFC10View 类的实现
//

#include "stdafx.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "MFC10.h"
#endif

#include "MFC10Set.h"
#include "MFC10Doc.h"
#include "MFC10View.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#include "resource.h"
#include "DevicesTable.h"
// CMFC10View

IMPLEMENT_DYNCREATE(CMFC10View, CRecordView)

BEGIN_MESSAGE_MAP(CMFC10View, CRecordView)
	// 标准打印命令
	ON_COMMAND(ID_FILE_PRINT, &CRecordView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CRecordView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CRecordView::OnFilePrintPreview)
	ON_COMMAND(ID_RECORD_FIRST, &CMFC10View::OnRecordFirst)
	ON_COMMAND(ID_RECORD_LAST, &CMFC10View::OnRecordLast)
	ON_COMMAND(ID_RECORD_NEXT, &CMFC10View::OnRecordNext)
	ON_COMMAND(ID_RECORD_PREV, &CMFC10View::OnRecordPrev)
	ON_BN_CLICKED(IDC_BUTTON1, &CMFC10View::OnBnClickedButton1)
	ON_BN_CLICKED(IDC_TagNames, &CMFC10View::OnClickedTagnames)
	ON_BN_CLICKED(IDC_KKSCode, &CMFC10View::OnClickedTagnames)
	ON_BN_CLICKED(IDC_Descriptors, &CMFC10View::OnClickedTagnames)
	ON_BN_CLICKED(IDC_PointType, &CMFC10View::OnClickedTagnames)
	ON_BN_CLICKED(IDC_BUTTON2, &CMFC10View::OnBnClickedButton2)
END_MESSAGE_MAP()

// CMFC10View 构造/析构

CMFC10View::CMFC10View()
	: CRecordView(CMFC10View::IDD)
	, m_filter(_T(""))
{
	m_pSet = NULL;
	// TODO: 在此处添加构造代码

}

CMFC10View::~CMFC10View()
{
}

void CMFC10View::DoDataExchange(CDataExchange* pDX)
{
	CRecordView::DoDataExchange(pDX);
	// 可以在此处插入 DDX_Field* 函数以将控件“连接”到数据库字段,例如
	// DDX_FieldText(pDX, IDC_MYEDITBOX, m_pSet->m_szColumn1, m_pSet);
	// DDX_FieldCheck(pDX, IDC_MYCHECKBOX, m_pSet->m_bColumn2, m_pSet);
	// 有关详细信息,请参阅 MSDN 和 ODBC 示例
	DDX_FieldText(pDX, IDC_EDIT1, (CString)m_pSet->m_TagNames, m_pSet);
	DDX_FieldText(pDX, IDC_EDIT2, (CString)m_pSet->m_KKSCode, m_pSet);
	DDX_FieldText(pDX, IDC_EDIT3, (CString)m_pSet->m_Descriptors, m_pSet);
	DDX_FieldText(pDX, IDC_EDIT4, (CString)m_pSet->m_PointType, m_pSet);
	//  DDX_Radio(pDX, IDC_TagNames, m_select);
	DDX_Text(pDX, IDC_FILTER, m_filter);
}

BOOL CMFC10View::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式

	return CRecordView::PreCreateWindow(cs);
}

void CMFC10View::OnInitialUpdate()
{
	m_pSet = &GetDocument()->m_MFC10Set;
	CheckRadioButton(IDC_TagNames,IDC_PointType,IDC_TagNames);
	m_strSel="TagNames";
	
	CRecordView::OnInitialUpdate();

}
void CMFC10View::Query()
{
	// 默认准备
	m_pSet->m_strSort=m_strSel;
	if(m_filter!="")
		m_pSet->m_strFilter=m_strSel+"="+m_filter;
	m_pSet->Requery();
	OnRecordFirst();
}

// CMFC10View 打印

BOOL CMFC10View::OnPreparePrinting(CPrintInfo* pInfo)
{
	// 默认准备
	return DoPreparePrinting(pInfo);
}

void CMFC10View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加额外的打印前进行的初始化过程
}

void CMFC10View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加打印后进行的清理过程
}


// CMFC10View 诊断

#ifdef _DEBUG
void CMFC10View::AssertValid() const
{
	CRecordView::AssertValid();
}

void CMFC10View::Dump(CDumpContext& dc) const
{
	CRecordView::Dump(dc);
}

CMFC10Doc* CMFC10View::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMFC10Doc)));
	return (CMFC10Doc*)m_pDocument;
}
#endif //_DEBUG


// CMFC10View 数据库支持
CRecordset* CMFC10View::OnGetRecordset()
{
	return m_pSet;
}



// CMFC10View 消息处理程序


void CMFC10View::OnRecordFirst()
{
	// TODO: 在此添加命令处理程序代码
	if(m_pSet->IsOpen())
	{
		m_pSet->MoveFirst();	
		this->UpdateData(false);
	}	
}
void CMFC10View::OnRecordLast()
{
	// TODO: 在此添加命令处理程序代码
	if(m_pSet->IsOpen())
	{
		m_pSet->MoveLast();
		this->UpdateData(false);
	}	
}
void CMFC10View::OnRecordNext()
{
	// TODO: 在此添加命令处理程序代码
	if(m_pSet->IsOpen())
	{
		m_pSet->MoveNext();
		this->UpdateData(false);
	}
	
}


void CMFC10View::OnRecordPrev()
{
	// TODO: 在此添加命令处理程序代码
	if(m_pSet->IsOpen())
	{
		m_pSet->MovePrev();
		this->UpdateData(false);
	}
	
}


void CMFC10View::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	
	Query();
}


void CMFC10View::OnClickedTagnames()
{
	// TODO: 在此添加控件通知处理程序代码
	if(IsDlgButtonChecked(IDC_TagNames))
		m_strSel="TagNames";

	if(IsDlgButtonChecked(IDC_KKSCode))
		m_strSel="KKSCode";
	if(IsDlgButtonChecked(IDC_Descriptors))
		m_strSel="Descriptors";
	if(IsDlgButtonChecked(IDC_PointType))
		m_strSel="PointType";

	
}



void CMFC10View::OnBnClickedButton2()
{
	// TODO: 在此添加控件通知处理程序代码
	
	Query();
}

结论:

1、MFC ODBC使用起来比较简单,很容易就可以完成数据库类的生成,捆绑的数据表为CRecordSet的派生类(自动生成),并且嵌在文档类中:

对数据库中指定表的操作就是通过该对象来完成(增删查改),示例中视图通过获取文档类指针来获得记录集对象:

 2、MFC ODBC创建工程时只能添加一张表,生成对应的记录集类(选择多张表会合并成一个类,很明显不对)。如果需要对数据库中多张表格的操作,可以通过类向导中选择添加ODBC类:

 注意使用的时候需要先Open:

	CDevicesTable devSet; //新增的另外一张表
	devSet.Open();
	devSet.Requery();
	devSet.MoveFirst();

3、可以用表生成对应的集合类,也可以用视图生成(解决左右连接等跨表查询等);

4、可以利用代码动态生成DSN(否则在其他电脑上运行程序需要手动先创建DSN);

5、很显然,MFC ODBC只适用于比较简单是数据库操作,复杂的数据库操作实现起来并不容易。

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
VC++(MFC)数据库程序开发,需要以下几个步骤: 1. 创建数据库 2. 创建表 3. 编写 VC++(MFC)程序 4. 连接数据库 5. 增删改查数据 下面,我们一步一步来实现一个简单的 VC++(MFC)数据库程序。 1. 创建数据库 我们使用 Microsoft SQL Server 数据库。首先,在 SQL Server Management Studio 中创建一个新的数据库。假设我们的数据库名称为 "TestDB"。 2. 创建表 在 "TestDB" 数据库中,创建一个新的表 "Student"。该表包含以下字段: - 学生编号(StudentID):int 类型,主键,自增长 - 姓名(Name):nvarchar(50) 类型 - 年龄(Age):int 类型 - 性别(Gender):nvarchar(10) 类型 3. 编写 VC++(MFC)程序 打开 VC++(MFC) 编辑器,创建一个新的 MFC 应用程序。在 "应用程序类型" 中选择 "单文档",在 "使用 MFC 的类型" 中选择 "使用数据库支持"。 4. 连接数据库 在 "OnInitInstance" 函数中,添加以下代码: ```c++ if (!AfxDaoInit()) { AfxMessageBox("Failed to initialize DAO!"); return FALSE; } CDatabase database; if (!database.OpenEx(_T("ODBC;DSN=TestDB;UID=sa;PWD=123456"))) { AfxMessageBox("Failed to open database!"); return FALSE; } CDaoDatabase* pDaoDB = &database; ``` 这里,我们使用 ODBC 连接数据库。"DSN" 是数据源名称,"UID" 和 "PWD" 是登录数据库的用户名和密码。当然,你也可以使用其他的数据库连接方式。 5. 增删改查数据 在 "Student" 表中插入一条记录: ```c++ CDaoRecordset recordset(pDaoDB); recordset.Open(dbOpenDynaset, _T("SELECT * FROM Student"), dbAppendOnly); recordset.AddNew(); recordset.SetFieldValue(_T("Name"), _T("张三")); recordset.SetFieldValue(_T("Age"), 20); recordset.SetFieldValue(_T("Gender"), _T("男")); recordset.Update(); ``` 在 "Student" 表中查询记录: ```c++ CDaoRecordset recordset(pDaoDB); recordset.Open(dbOpenDynaset, _T("SELECT * FROM Student"), dbReadOnly); CString strResult; while (!recordset.IsEOF()) { CString strName, strGender; int nAge; recordset.GetFieldValue(_T("Name"), strName); recordset.GetFieldValue(_T("Age"), nAge); recordset.GetFieldValue(_T("Gender"), strGender); strResult.Format(_T("%s\t%d\t%s"), strName, nAge, strGender); AfxMessageBox(strResult); recordset.MoveNext(); } ``` 在 "Student" 表中更新记录: ```c++ CDaoRecordset recordset(pDaoDB); recordset.Open(dbOpenDynaset, _T("SELECT * FROM Student"), dbAppendOnly); recordset.MoveFirst(); recordset.SetFieldValue(_T("Age"), 21); recordset.Update(); ``` 在 "Student" 表中删除记录: ```c++ CDaoRecordset recordset(pDaoDB); recordset.Open(dbOpenDynaset, _T("SELECT * FROM Student"), dbAppendOnly); recordset.MoveFirst(); recordset.Delete(); ``` 到此为止,我们就完成了一个简单的 VC++(MFC)数据库程序。当然,这只是一个入门级别的程序,实际开发中还需要更多的功能和处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

易老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值