配置ODBC数据源,MFC操作MySql数据库(VS2015环境下)

先来看下最终程序的运行效果吧
运行程序,点击查询所有,将是数据库中的信息显示到ListContrl控件上,鼠标点击ListContrl控件的某一行,将对应的球员信息显示到右边的编辑框中,方便修改。
在这里插入图片描述
来看看与数据库中的信息是否一致
在这里插入图片描述
接下来看看具体如何实现呢?
既然是用ODBC操作数据库,首先,我们得先创建一个ODBC的数据源,如果已经创建了ODBC数据源的小伙伴,这部分就可以跳过啦。
打开电脑的控制面板->系统和安全->管理工具,会看到如下界面
在这里插入图片描述
因为我这里使用的ODBC驱动是32位的驱动,所以我们选择配置32位的数据源
在这里插入图片描述
在这里插入图片描述此处的IP地址填本机地址,也可以写localhost,User和Password写你Mysql的用户名和密码,Database选择你想要操作的数据库,之后点击Test,若果弹出如图所示的连接成功提示,表示测试成功,点击Ok,我们就会看到界面多出了我刚才创建的数据源。
在这里插入图片描述
数据源到此创建完毕,接下我们进入第二步。
新建一个基于对话框的MFC应用程序,我这里命名为ODBC-Test,来看看创建完项目后的解决方案
在这里插入图片描述
对界面进行如下布局,布局可能不是很好看,当个例子,大家凑合看吧,之后打开类向导可以看到对相应的控件添加了如下变量,这里记得吧ListContrl控件的属性中的View改为Report。
在这里插入图片描述
在这里插入图片描述
界面搭建完成,下一步开始上代码实现。
在ODBC-TestDlg.h中加入以下头文件,以提供ODBC对象来对数据库进行访问。

#include "afxcmn.h"
#include <odbcinst.h> 
#include "afxdb.h"
#include "afxwin.h"

稍加思考,我们只等读取数据库的数据到ListContrl控件上,但是控件的第一行ID、Name、Height、Weight这4个是要我们自己初始化的,因此在初始化对话框函数 OnInitDialog() 中接入下列代码来给ListContrl控件设置风格和标题。

//设定风格样式
	m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
	//在Listctrl控件上添加列,与数据库table对应。
	/*
	第一个参数表示需要设置的列
	第二个参数表示要给该列填充的值
	第三个参数表示填充的值以什么风格显示,这里我们使用居中显示
	第四个参数表示给该列分配的宽度
	*/
	m_list.InsertColumn(0, _T("ID"), LVCFMT_CENTER, 50);
	m_list.InsertColumn(1, _T("Name"), LVCFMT_CENTER, 100);
	m_list.InsertColumn(2, _T("Height"), LVCFMT_CENTER, 80);
	m_list.InsertColumn(3, _T("Weight"), LVCFMT_CENTER, 80);

初始化工作完成后,因为考虑到后面在每次对数据库进行操作的时候,我们想让数据库中的数据同步显示到ListContrl控件中,因此我们可以把查询数据库的代码封装成一个函数,到时候在每次对数据库进行操作完毕后,直接调用查询函数就可以。

//查询函数
void CODBCTestDlg::show(CString cmdStr)
{
	//清空ListContrl控件
	m_list.DeleteAllItems();
	/*声明一个数据库对象,因为要调用相关的方法来操作数据库,
	那怎么调用呢,肯定要先有对象嘛,没有对象,还怎么玩,
	是这个道理吧*/
	CDatabase db;
	//这里的DSN就是我们刚刚创建的数据源,UID,PWD对应的就是账户和密码
	db.Open(NULL, FALSE, FALSE, L"ODBC;DSN=NBA;UID=root;PWD=root");
	//声明一个记录集对象,用来对数据库进行操作
	CRecordset rs(&db);
	rs.Open(CRecordset::forwardOnly, (L"%s", cmdStr));
	int count = 0;
	while (!rs.IsEOF())
	{
		/*要往ListContrl中填充数据库的数据,那就要先给控件开辟一行,
		在向这一行里面的每列填充数据,注意,先开辟行*/
		m_list.InsertItem(count, _T(""));
		CString varID;
		rs.GetFieldValue(L"id", varID);
		m_list.SetItemText(count, 0, varID);
		CString varName;
		rs.GetFieldValue(L"name", varName);
		m_list.SetItemText(count, 1, varName);
		CString varHeight;
		rs.GetFieldValue(L"height", varHeight);
		m_list.SetItemText(count, 2, varHeight);
		CString varWeight;
		rs.GetFieldValue(L"weight", varWeight);
		m_list.SetItemText(count, 3, varWeight);
		count++;
		rs.MoveNext();
	}
	rs.Close();
	db.Close();
}

接下来,我们来查询数据库中所有球员的信息,因为我们刚刚已经把查询函数封装完毕,因此这一步会异常简单,有多简单呢,2行代码搞定

//查询素有球员信息
void CODBCTestDlg::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	CString cmdStr = _T("select * from players");
	show(cmdStr);
}

到此,就可以运行程序看一下是否可以查询出来所有信息了,我这里就不上图了,接着往下走,来写添加球员的函数。
添加球员,我们先分析一下思路,要添加球员的信息肯定是要从编辑框中获得的,之后再用一个sql语句来向数据库中插入信息

//添加
void CODBCTestDlg::OnBnClickedButton2()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData(TRUE);
	CDatabase db;
	db.Open(NULL, FALSE, FALSE, _T("ODBC;DSN=NBA;UID=root;PWD=root"));
	//获取四个编辑框的值
	CString str, Id, Name, Height, Weight;
	m_uiId.GetWindowTextW(Id);
	m_uiName.GetWindowTextW(Name);
	m_uiHeight.GetWindowTextW(Height);
	m_uiWeight.GetWindowTextW(Weight);
	str.Format(L"insert into players values('%s', '%s', '%s', '%s')",Id, Name, Height, Weight);
	//执行Sql语句向数据库中插入数据
	db.ExecuteSQL(str);
	db.Close();
	MessageBox(TEXT("添加成功"));
	//调用查询函数,让数据库的信息同步更新到控件上
	CString cmdStr = TEXT("select * from players");
	show(cmdStr);
}

接下来是删除吧,说到删除这里,其实有很多思路,可以直接根据ID来删除,也可以更严谨一点,加上姓名、身高、体重等作为判断依据,我们这里做的更严谨一点,先判断鼠标是否点击到ListContrl控件中的某行,如果点击到了,直接获取这一行的信息来作为删除的依据,如果没有点击到控件内,就获取编辑框的内容来作为删除的依据。不过,其实稍加思考就知道,要是两者都没有,还可以弹个提示框提醒用户选择要删除的信息,这个,就留着有兴趣的再添加吧,毕竟难度不大,对吧。

//删除
void CODBCTestDlg::OnBnClickedButton3()
{
	// TODO: 在此添加控件通知处理程序代码
	CDatabase db;
	db.Open(NULL, FALSE, FALSE, _T("ODBC;DSN=NBA;UID=root;PWD=root"));
	int nIndex;
	CString Id, Name, Height, Weight;
	//获取当前鼠标在ListContrl中的位置
	nIndex = m_list.GetNextItem(-1, LVNI_ALL | LVNI_SELECTED);
	if (nIndex != -1)
	{
		Id = m_list.GetItemText(nIndex, 0);
		Name = m_list.GetItemText(nIndex, 1);
		Height = m_list.GetItemText(nIndex, 2);
		Weight = m_list.GetItemText(nIndex, 3);
	}
	else
	{
		//获取编辑框的内容
		m_uiId.GetWindowTextW(Id);
		m_uiName.GetWindowTextW(Name);
		m_uiHeight.GetWindowTextW(Height);
		m_uiWeight.GetWindowTextW(Weight);
	}
	CString str;
	str.Format(TEXT("delete from players where id='%s' and name='%s' and height='%s' and weight='%s'"),
		Id, Name, Height, Weight);
	db.ExecuteSQL(str);
	db.Close();
	MessageBox(TEXT("删除成功"));
	CString strCmd = TEXT("select * from players");
	show(strCmd);

}

终于来到最后一个更新功能,思路依然要清晰,更新,肯定也是当鼠标点击某个球员信息的时候,将信息同步更新到编辑框中,然后获取编辑框的值来作为更新的依据。

//修改
void CODBCTestDlg::OnBnClickedButton4()
{
	// TODO: 在此添加控件通知处理程序代码
	CDatabase db;
	db.Open(NULL, FALSE, FALSE, _T("ODBC;DSN=NBA;UID=root;PWD=root"));
	CString Id, Name, Height, Weight;
	m_uiId.GetWindowTextW(Id);
	m_uiName.GetWindowTextW(Name);
	m_uiHeight.GetWindowTextW(Height);
	m_uiWeight.GetWindowTextW(Weight);
	CString updateStr;
	updateStr.Format(TEXT("update players set name='%s', height='%s',weight='%s' where id='%s'"),
		Name, Height, Weight, Id);
	db.ExecuteSQL(updateStr);
	db.Close();
	MessageBox(TEXT("更新成功"));
	CString strCmd = TEXT("select * from players");
	show(strCmd);

}

差点忘了,还差个鼠标点击某行,把相应的信息显示到编辑框中。这里我们调用一个ListContrl控件的鼠标点击响应函数,具体方法,在对话框界面鼠标右键点击ListContrl,选择添加事件处理程序,找到对应的函数
在这里插入图片描述

//鼠标点击某行,将对应的信息显示到控件上
void CODBCTestDlg::OnNMClickList1(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	int nIndex = 0;
	if (nIndex == -1)
		nIndex = 0;
	//获取鼠标当前选中的行
	nIndex = m_list.GetNextItem(-1, LVNI_ALL | LVNI_SELECTED);
	//将该行的信息显示到编辑框中
	m_uiId.SetWindowTextW(m_list.GetItemText(nIndex, 0));
	m_uiName.SetWindowTextW(m_list.GetItemText(nIndex, 1));
	m_uiHeight.SetWindowTextW(m_list.GetItemText(nIndex, 2));
	m_uiWeight.SetWindowTextW(m_list.GetItemText(nIndex, 3));
	*pResult = 0;
}

到此,大功告成,可以运行一下程序,享受一下运行成功的那种快乐了,当然,如果你不幸出了bug,也不要惊慌,毕竟改bug才能更好的体会编程的乐趣,所以说,直接运行成功的乐趣已经少了一半了。

猜你喜欢

转载自blog.csdn.net/polkmn666/article/details/107904269