MFC连接MySQL数据库实例

时间:2021-02-24 13:10:11

关于项目配置请参考这篇文章
http://blog.csdn.net/qq_18297675/article/details/52239881

关于乱码问题请参考这篇文章
http://blog.csdn.net/qq_18297675/article/details/52240029

需要注意的是,在MFC中有些函数的参数类型是LPCTSTR的,这样就算数据库返回的数据不乱码,你把它强制转换后还是会乱码的。所以MFC中要把字符集改成多字节,这样LPCTSTR就会自动转换为LPCSTR,这是C语言的const char*类型,这样就不会乱码了。

程序效果如图:
MFC连接MySQL数据库实例

MFC连接MySQL数据库实例

MFC连接MySQL数据库实例

程序源码:链接:http://pan.baidu.com/s/1nvvraHz 密码:le63

大概思路如下:
1.把数据库操作分为以下几个部分

1)连接数据库函数

2)select数据库函数

3)insert数据库函数

4)delete数据库函数

5)从结果集中获取数据函数

6)显示数据到列表中

2.其它按钮的功能就是调用上面那些函数

部分代码如下:
连接数据库:

    //初始化数据库
mysql_init(&m_mysql);
//设置数据库编码格式
mysql_options(&m_mysql, MYSQL_SET_CHARSET_NAME, "gbk");
//连接数据库
if (!mysql_real_connect(&m_mysql, HOST, USER, PASSW, DBNAME, PORT, NULL, 0))
return FALSE;
return TRUE;

查询数据:

    UpdateData(TRUE);
ClearData();
CString query;
//条件全部为空则查询所有书籍
if (m_queryBook.IsEmpty() && m_queryAuthor.IsEmpty() && !m_priceMin && !m_priceMax)
query.Format(TEXT("select * from book"));
else if (!m_priceMin && !m_priceMax)//价格范围为空
{
CString sBook,sAuthor;
if (!m_queryBook.IsEmpty())
{
sBook.AppendChar('%');
m_queryBook.AppendChar('%');
sBook.Append(m_queryBook);
}
if (!m_queryAuthor.IsEmpty())
{
sAuthor.AppendChar('%');
m_queryAuthor.AppendChar('%');
sAuthor.Append(m_queryAuthor);
}
query.Format(TEXT("select * from book where 书名 like '%s' or 作者 like '%s';"), sBook, sAuthor);
}
else if (m_priceMin && !m_priceMax)
query.Format(TEXT("select * from book where 售价 >= %f;"), m_priceMin);
else if (!m_priceMin && m_priceMax)
query.Format(TEXT("select * from book where 售价 <= %f;"), m_priceMax);
else if (m_priceMin && m_priceMax)
query.Format(TEXT("select * from book where 售价 >= %f and 售价 <=%f;"), m_priceMin,m_priceMax);
//查询数据
if (mysql_query(&m_mysql, query))
return FALSE;
//获取结果集
m_res = mysql_store_result(&m_mysql);
return TRUE;

插入数据:

    UpdateData(TRUE);
if (m_addBook.IsEmpty())
{
AfxMessageBox(TEXT("书名不能为空!"));
return FALSE;
}
CString query;
query.Format(TEXT("insert into book values(NULL,'%s','%s','%s','%s',%.2f);"), m_addBook, m_addAuthor, m_addPublisher, m_addTime, m_addPrice);
if (mysql_query(&m_mysql, query))
{
AfxMessageBox(TEXT("插入数据失败!"));
return FALSE;
}
return TRUE;

删除数据:

    UpdateData(TRUE);
int iCount = m_list.GetItemCount();
std::vector<std::string> row[100];
int j = 0;
//可以多选然后删除
for (int i = iCount; i >= 0; i--)
{
if (m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED)
{
CString bookName;
bookName = m_list.GetItemText(i, 0);
CString query;
query.Format(TEXT("delete from book where 书名='%s';"), bookName);
if (mysql_query(&m_mysql, query))
{
AfxMessageBox(TEXT("删除数据失败!"));
return FALSE;
}
//要先删除数据库的记录后才能删除列表中的项,否则GetItemText会返回空
m_list.DeleteItem(i);//删除列表中的项
}
}
return TRUE;

获取数据:

    //获取记录
int i = 0;
while (m_row = mysql_fetch_row(m_res))
{
m_data[i].push_back(m_row[0]);
m_data[i].push_back(m_row[1]);
m_data[i].push_back(m_row[2]);
m_data[i].push_back(m_row[3]);
m_data[i].push_back(m_row[4]);
m_data[i++].push_back(m_row[5]);
}

显示数据:

    m_list.DeleteAllItems();  //先清空列表
for (int i = 0;i<m_res->row_count;i++)//记录条数
{
int iCount = m_list.GetItemCount();
m_list.InsertItem(iCount, m_data[i][1].c_str());
for (int j = 0;j < m_mysql.field_count - 2;j++)//字段数
m_list.SetItemText(iCount, j + 1,m_data[i][j + 2].c_str());
}

需要注意的是,数据库不要重复连接,所以一开始连接一次后下面就不用再调用那个函数了。结果集也不要释放,等关闭程序后再释放,数据库关闭也是一样的。