配置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才能更好的体会编程的乐趣,所以说,直接运行成功的乐趣已经少了一半了。
本文地址:https://blog.csdn.net/polkmn666/article/details/107904269
上一篇: 高通平台常用英文单词缩写
下一篇: 国内外比较出名的聚合路由器厂家都有哪些?