下面进行设置:
(1)项目—>属性—>配置属性—>C/C++—>附加包含目录:在附加包含目录中添加C:\Program Files\MySQL\MySQL Server 5.7\include(就是安装MySql下的include文件夹,将头文件包含)
(2)项目—>属性—>配置属性—>连接器—>常规—>附加库目录:C:\Program Files\MySQL\MySQLServer 5.7\lib(就是安装MySql下的lib文件夹,将库文件包含)
(3)连接器—>输入—>附加依赖项:添加libmysql.lib(若此处不添加,需要最后在头文件中添加#pragmacomment(lib,"libmysql.lib") )。
(4)编译通过之后,运行还要将C:\Program Files\MySQL\MySQLServer 5.7\lib(安装MySql下的lib文件夹)中的libmysql.dll拷到项目中的Debug文件夹中(或者拷到C:\Windows\System32中)。
下面在项目头文件或者要连接数据库的文件程序中添加头文件:
#include "winsock.h"
#include "mysql.h"
#include
#pragma comment(lib,"libmysql.lib")// (若未进行上面第(3)步设置,需要添加)
void CtestDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
MYSQL m_sqlCon;
MYSQL_RES* m_res; //查询的返回结果集
MYSQL_ROW m_row; //获取每一条记录
mysql_init(&m_sqlCon);
// localhost:服务器 root/123456为账号密码 managesystemdb为数据库名 3306为端口
if (!mysql_real_connect(&m_sqlCon, "localhost", "root", "root", "mydb", 3306, NULL, 0))
{
AfxMessageBox(_T("访问数据库失败!"));
CString e = mysql_error(&m_sqlCon);//需要将项目属性中字符集修改为“使用多字节字符集”或“未设置”
MessageBox(e);
return;
}
else
{
mysql_query(&m_sqlCon, "SET NAMES 'UTF-8'");//解决从数据库中读取数据后汉字乱码显示的问题
//查询数据
if (mysql_query(&m_sqlCon, "select * from user"))
return ;
//获取结果集
m_res = mysql_store_result(&m_sqlCon);
//获取记录
std::vector m_data[100]; //存放数据库记录,最大为100条
int i = 0;
while (m_row = mysql_fetch_row(m_res))
{
CString onerecord;
onerecord.Format("%s - %s - %s - %s - %s - %s\n", m_row[0], m_row[1], m_row[2], m_row[3], m_row[4], m_row[5]);
OutputDebugString(onerecord);
}
int a = 0;
}
}
由于系统是32位或者64位的不同,编译时会引起如下错误:
无法解析的外部符号 _mysql_real_connect, 无法解析的外部符号 _mysql_query,无法解析的外部符号 _mysql_init;
解决办法见:http://blog.csdn.net/u010439291/article/details/43898997
=======================================================================================
VS中建立MFC项目连接MySQL 的一般步骤见文章:《VS中MFC连接MySQL的方法》http://blog.csdn.net/u010439291/article/details/43889403
但是由于系统是32位或者64位的不同,编译时会引起如下错误:
无法解析的外部符号 _mysql_real_connect, 无法解析的外部符号 _mysql_query,无法解析的外部符号 _mysql_init;
对于32位只要按照上述文章即可。
对于64位,有两种方法解决上述错误:
方法一:由于VS建立的项目默认为WIN32 项目,需将平台改为64。设置如下:
(1) 项目—》属性—》配置属性—》配置管理器—》活动解决方案平台,下拉选新建,出现一个新的对号框,在键入选择新平台中选择X64,如下图所示:
(2)不是将C:\ProgramFiles\MySQL\MySQL Server 5.7\lib(安装MySql下的lib文件夹)中的libmysql.dll拷到项目下的Debug文件夹中,而是拷到项目下x64\Debug中(或者C:\Windows\System32中)。完毕。。
方法二:要包含32位的lib文件和dll文件。
32/64位MySql(lib、dll)资源: http://download.csdn.net/detail/u010439291/8453041
(1)首先下载32位的lib文件和dll文件。
(2)需要将32位的lib文件拷到C:\Program Files\MySQL\MySQL Server 5.7\lib(安装Mysql下的lib文件夹),拷贝之前需要将原来的libmysql.lib更名。也可以不改变原来的lib文件名称,而将32位的libmysql.lib 改为libmysql32.lib 同时在:
项目—>属性—>连接器—>输入—>附加依赖项:添加libmysql32.lib(名称和之前保持一致)。编译通过之后,运行还要将32位的libmysql.dll放在工程目录Debug文件夹中或者System32下。
===========================================================================================
关于项目配置请参考这篇文章
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*类型,这样就不会乱码了。
程序源码:链接: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;irow_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());
}
需要注意的是,数据库不要重复连接,所以一开始连接一次后下面就不用再调用那个函数了。结果集也不要释放,等关闭程序后再释放,数据库关闭也是一样的。