VS中MFC访问MySQL的方法

MFC连接MySQL的方法:首先建立一个MFC项目。

下面进行设置:

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 <vector>
#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<std::string> 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;
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

查询数据:

    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;
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

插入数据:

    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;
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

删除数据:

    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;
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

获取数据:

    //获取记录
    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]);
    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

显示数据:

    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());
    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值