目录
4.将List Box上的内容显示到Edit_Contrl控件上
前言
最近也是因为在学习MFC,一直想学学数据库相关的东西,就借此机会进行了一下学习
一.数据库的安装和增加数据
在CSDN上面,安装数据库和Navicat的教学很多,在这里就不过多赘述.
二.预期效果
以实现MFC对MySql数据库的增删改查操作.
三.MFC初始设置
本文是以基于MySql数据库进行操作,对国家的首都、和Gdp进行排列,连接好对应的数据库之后,点击任意一列就可以在下方进行显示当前选中行的信息,设置打开、插入、删除、修改、查询五个按钮,对应还有ID、Country、Capital、Gdp四个Edit_Control控件进行显示相应的数值.
在进行好整体的页面布局之后,因为要对Combo Box和List Box进行显示,所以对其进行关联相关的变量:
CComboBox m_db;//为Combo Box进行增添变量
CListCtrl m_list;//为List Box进行增添变量
1.MySql头文件的定义
public:
//为控件添加变量
CComboBox m_db;
CListCtrl m_list;
//定义一个MYSQL的数据库文件
MYSQL* m_instance;
//查询数据库代码
void DispBySql(CString sql);
//初始化数据库函数
void InitDatabase();
//打开按钮
afx_msg void OnBnClickedButtonOpen();
//ListBox控件显示
afx_msg void OnNMClickListDb(NMHDR* pNMHDR, LRESULT* pResult);
//增删改查四步操作
afx_msg void OnBnClickedButtonInsert();
afx_msg void OnBnClickedButtonDelete();
afx_msg void OnBnClickedButtonModify();
afx_msg void OnBnClickedButtonQuery();
2.添加初始化函数
void CMySqlDlg::InitDatabase()
{
//初始化一个字符串
CString strLine;
//初始化对应的MYSQL对象,后面的操作都会用到该对象
//初始化一个Mysql对象
m_instance = mysql_init(NULL);
//2.连接MYSQL_SEVER数据库
//连接数据库的方法
mysql_real_connect(m_instance, NULL, "", "", NULL, 0000, NULL, 0);
//3.显示MYSQL_SEVER数据库中的数据
//这个resultSet就是从数据库中遍历显示的数据
MYSQL_RES* resultSet = mysql_list_dbs(m_instance, NULL);
//数据库对应是从行进行遍历的结果
MYSQL_ROW row;//这个是数据库的一行的元素
while (row = mysql_fetch_row(resultSet))//row就获取到了mysql数据库一行的数据
{
//进行遍历数据库每行的元素
//格式化strline
//遍历显示数据库的名称
strLine.Format(_T("database:%s"), row[0]);
MessageBox(strLine);
//ComboBox遍历m_db的文本框
m_db.AddString(row[0]);
}
//默认选中首元素
m_db.SetCurSel(0);
//释放掉resultSet
mysql_free_result(resultSet);
}
这里仅仅提供给连接数据库的方法,大家在自己连接数据库的时候,要参考相应的变量类型填写.
3.打开数据库
void CMySqlDlg::OnBnClickedButtonOpen()
{
// TODO: 在此添加控件通知处理程序代码
//切换数据库
CString strDbName;
m_db.GetLBText(m_db.GetCurSel(), strDbName);
mysql_select_db(m_instance, strDbName);
mysql_set_character_set(m_instance, "utf8");//不乱码
//2.查询数据库
DispBySql("select *from country");
}
void CMySqlDlg::DispBySql(CString sql)
{
//1.删除列表控件中的数据
int nColumnCount = m_list.GetHeaderCtrl()->GetItemCount();
for (int i = 0; i < nColumnCount; i++)
{
m_list.DeleteColumn(0);//删除头部标题
}
m_list.DeleteAllItems();//删除所有行的数据
//2.根据sql语句查询数据库
//查询数据库
mysql_query(m_instance, sql);
//保存数据库中的信息
//resultSet代表数据表中的每一行的数据
MYSQL_RES* resultSet = mysql_store_result(m_instance);
//如果数据库中的没有对应的信息的话
if (!resultSet)
{
//可能是数据出现错误
MessageBox(_T("出现错误,可能:数据库中没有对应的表..."), _T("MYSQL"), MB_OK | MB_ICONERROR);
return;
}
//3.插入头部
//遍历对应字符串的名称
//数据库的宽高
CRect rect;
//把宽高进行四等分
m_list.GetWindowRect(&rect);
MYSQL_FIELD* filed;//这是一个域 这个域就是把数据库中每个数据库的信息给遍历出来
for (int i = 0; filed = mysql_fetch_field(resultSet); i++)
{
//每列的信息都是对应的平均分配的
m_list.InsertColumn(i, filed->name, LVCFMT_LEFT, rect.Width() / mysql_num_fields(resultSet));
}
//获取数据库中的真实数据行
if (mysql_num_rows(resultSet) <= 0)
{
MessageBox(_T("数据库中没有任何记录"), _T("MYSQL"), MB_OK | MB_ICONWARNING);
return;
}
//4.插入真实数据
int nRow = 0;
MYSQL_ROW row;//获取数据库一行的数据 row对应是一个二级指针
while (row = mysql_fetch_row(resultSet))//获取到一行的真实数据
{
int nField = mysql_num_fields(resultSet);//获取到MySql数据库的字段//对应看他们有多少字段
for (int i = 0; i < nField; i++)
{
if (i == 0)
{
m_list.InsertItem(nRow, row[i]);//插入第一列
}
else
{
m_list.SetItemText(nRow, i, row[i]);//插入第二三四列
}
}
nRow++;
}
mysql_free_result(resultSet);
}
4.将List Box上的内容显示到Edit_Contrl控件上
void CMySqlDlg::OnNMClickListDb(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
*pResult = 0;
NMLISTVIEW* pListView = (NMLISTVIEW*)pNMHDR;
//pListView->iTem 代表选中的那一行
if (-1 != pListView->iItem)//对应pListView->iItem!=-1代表我们选中一行
{
CString strId = m_list.GetItemText(pListView->iItem, 0);
CString strCountry = m_list.GetItemText(pListView->iItem, 1);
CString strCapital = m_list.GetItemText(pListView->iItem, 2);
CString strGdp = m_list.GetItemText(pListView->iItem, 3);
//显示到下面的文本框中
SetDlgItemText(IDC_EDIT_ID, strId);
SetDlgItemText(IDC_EDIT_COUNTRY, strCountry);
SetDlgItemText(IDC_EDIT_CAPITAL, strCapital);
SetDlgItemText(IDC_EDIT_GDP, strGdp);
}
//获取到数据库中的字符串
}
四.数据库的增删改查操作
1.数据库增添操作
MFC对于数据库的增添操作的话,就是对应向数据库中添加相应的数据,而且还要将对应的strId进行相应的排序:
void CMySqlDlg::OnBnClickedButtonInsert()
{
// TODO: 在此添加控件通知处理程序代码
//从Edit_Control控件上获取数据
CString strId, strCountry, strCapital, strGdp;
GetDlgItemText(IDC_EDIT_ID, strId);
GetDlgItemText(IDC_EDIT_COUNTRY, strCountry);
GetDlgItemText(IDC_EDIT_CAPITAL, strCapital);
GetDlgItemText(IDC_EDIT_GDP, strGdp);
//拼接SQL语句
CString strSql;
strSql = _T("insert into country(id,country,capital,gdp) values(");
strSql += strId + _T(",\'") + strCountry + _T("\',\'") + strCapital + _T("\',") + strGdp + _T(")");
MessageBox(strSql);
//strID不能为空
if (strId.IsEmpty())
{
MessageBox(_T("至少要输入ID"), _T("插入操作"), MB_ICONWARNING);
return;
}
//执行sql语句
int res = mysql_query(m_instance, strSql);
if (res)
{
MessageBox(_T("插入数据失败:ID已经存在,或者ID错误"), _T("插入操作"), MB_ICONWARNING);
return;
}
//显示列表框
m_list.InsertItem(0, strId);
m_list.SetItemText(0, 1, strCountry);//对应的分别是行,第几列 对应国家是第二列,已经对应的数据
m_list.SetItemText(0, 2, strCapital);
m_list.SetItemText(0, 3, strGdp);
m_list.SortItemsEx(ListCompareFunc, (DWORD_PTR)&m_list);
}
因为牵扯到要将strId进行排序,排序函数如下:
int CALLBACK ListCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
CListCtrl* pListCtrl = (CListCtrl*)lParamSort;
CString strId1 = pListCtrl->GetItemText(lParam1, 0);
CString strId2 = pListCtrl->GetItemText(lParam2, 0);
int iId1 = _tstoi(strId1.GetBuffer());
int iId2 = _tstoi(strId2.GetBuffer());
//如果需要交换这两行 则返回>0的值
return iId1 - iId2;
}
预期实现:
2.数据库删除操作
void CMySqlDlg::OnBnClickedButtonDelete()
{
// TODO: 在此添加控件通知处理程序代码
//增删改查的内容操作
//获取字符串
CString strId, strCountry, strCapital, strGdp;
GetDlgItemText(IDC_EDIT_ID, strId);
GetDlgItemText(IDC_EDIT_COUNTRY, strCountry);
GetDlgItemText(IDC_EDIT_CAPITAL, strCapital);
GetDlgItemText(IDC_EDIT_GDP, strGdp);
//刚开始的删除条件
if (strId.IsEmpty() && strCountry.IsEmpty() && strCapital.IsEmpty() && strGdp.IsEmpty())
{
//输入条件不能为空
MessageBox(_T("删除条件不能为空"), _T("删除操作"), MB_ICONWARNING);
return;
}
CString strSql;
strSql = _T("delete from country where ");
if (!strId.IsEmpty())
{
strSql += _T("id=") + strId;
}
if (!strCountry.IsEmpty())
{
if (strId.IsEmpty())
{
strSql += _T("country=\'") + strCountry + (_T("\'"));
}
else
{
strSql += _T("and country=\'") + strCountry + (_T("\'"));
}
}
//判断capital
if (!strCapital.IsEmpty())
{
if (strId.IsEmpty() && strCountry.IsEmpty())
{
strSql += _T("capacity=\'") + strCountry + (_T("\'"));
}
else
{
//这里就是判断中间有一个为空的
strSql += _T("and capacity=\'") + strCountry + (_T("\'"));
}
}
if (!strGdp.IsEmpty())
{
if (strId.IsEmpty() && strCountry.IsEmpty() && strGdp.IsEmpty())
{
strSql += _T("gdp=") + strGdp;
}
else
{
strSql += _T("and gdp=") + strGdp;
}
}
MessageBox(strSql);
//执行
//从数据库中删除
mysql_query(m_instance, strSql);
//更新列表显示
DispBySql(_T("select* from country"));
}
3.数据库修改操作
void CMySqlDlg::OnBnClickedButtonModify()
{
// TODO: 在此添加控件通知处理程序代码
CString strId, strCountry, strCapital, strGdp;
GetDlgItemText(IDC_EDIT_ID, strId);
GetDlgItemText(IDC_EDIT_COUNTRY, strCountry);
GetDlgItemText(IDC_EDIT_CAPITAL, strCapital);
GetDlgItemText(IDC_EDIT_GDP, strGdp);
//在进行修改的过程中,ID不能等于空
if (strId.IsEmpty())
{
MessageBox(_T("请输入要修改的Id"), _T("修改操作"), MB_ICONWARNING);
return;
}
//update country set country='china'
//根据ID进行修改
CString strSql = _T("update country set ");
strSql += _T("country=\'") + strCountry + _T("\'");
strSql += _T(",capital=\'") + strCapital + _T("\'");
strSql += _T(",gdp=") + strGdp;
strSql += _T(" where id=") + strId;
//列表显示
MessageBox(strSql);
mysql_query(m_instance, strSql);
//更新列表显示
DispBySql(_T("select* from country"));
}
预期实现:
可以看到对应的Navicat上也已经发生了改变:
4.数据库查询操作
void CMySqlDlg::OnBnClickedButtonQuery()
{
// TODO: 在此添加控件通知处理程序代码
CString strId, strCountry, strCapital, strGdp;
GetDlgItemText(IDC_EDIT_ID, strId);
GetDlgItemText(IDC_EDIT_COUNTRY, strCountry);
GetDlgItemText(IDC_EDIT_CAPITAL, strCapital);
GetDlgItemText(IDC_EDIT_GDP, strGdp);
//selet* from country
CString strSql;
if (strId.IsEmpty() && strCountry.IsEmpty() && strCapital.IsEmpty() && strGdp.IsEmpty())
{
strSql = _T("select * from country");
}
else
{
strSql = _T("Select * from country where ");
if (!strId.IsEmpty())
{
strSql += _T("id=") + strId;
}
//接着
if (!strCountry.IsEmpty())
{
if (strId.IsEmpty())
{
strSql += _T("country=\'") + strCountry + _T("\'");
}
else
{
strSql += _T(" and country=\'") + strCountry + _T("\'");
}
}
if (!strCapital.IsEmpty())
{
if (strId.IsEmpty() && strCountry.IsEmpty())
{
strSql += _T("capital=\'") + strCapital + _T("\'");
}
else
{
strSql += _T(" and capital=\'") + strCapital + _T("\'");
}
}
//最后结束
if (!strGdp.IsEmpty())
{
if (strId.IsEmpty() && strCountry.IsEmpty() && strCapital.IsEmpty())
{
strSql += _T("gdp=") + strGdp;
}
else
{
strSql += _T(" and gdp=") + strGdp;
}
}
}
//先进行弹窗显示一下
MessageBox(strSql);
DispBySql(strSql);
}
预期实现:
当所有的输入均为空时,显示数据库中的所有数据:
就此,所有操作就结束了!我是老胡,持续更新自己的学习历程!