MySQL编程需要包含<mysql.h>头文件。该文件一般在MySQL安装目录下的include文件夹下。
包含头文件还不够,还需要包含“libmysql.lib”库,一般在lib文件夹下。
MySQL编程与Socket编程非常相似,唯一不同的是MySQL使用的是MYSQL结构体,而Socket使用的是SOCKET。因此需要先构建一个MYSQL结构体并初始化(mysql_init),使用完后需要释放该结构体(mysql_close)。
函数详情可查看MYSQL参考手册
下载地址:链接:https://pan.baidu.com/s/1qZ96XtU 密码:zk5l
// MySQL.h
#ifndef C_MYSQL_H // 防止多次包含 #define C_MYSQL_H // 导出/导入函数 #ifdef MYSQL_EXPORTS #define MYSQLAPI __declspec(dllexport) #else #define MYSQLAPI __declspec(dllimport) #endif // 头文件 #include "stdafx.h" #include <WinSock2.h> #include "X:\Program Files\MySQL\MySQL Server 5.5\include\mysql.h" #include <string> using std::string; #pragma comment(lib, "libmysql.lib")// 链接动态库 #pragma warning(disable:4251)// 屏蔽编译警告 #pragma warning(disable:4267) #pragma warning(disable:4244) class MYSQLAPI CMySQL { public: CMySQL(); virtual ~CMySQL(); public: // 返回错误描述 string GetErrorDesc(__in int nErrorID); // 返回错误ID int GetErrorID(); // 连接MySQL数据库 bool Connect(__in string szIpAddr/*Ip地址*/, __in unsigned int unPort/*端口号*/, __in string szUser/*用户名*/, __in string szPass/*密码*/, __in string szDatabase/*库名称*/); // 向数据库发送指令 bool Command(__in string szComm); // 接收结果 virtual bool Result(__out string **pOutBuf, __out int *pNum); protected: MYSQL *m_pMySQL; int m_nErrorID; }; #endif // C_MYSQL_H
// MySQL.cpp
// MySQL.cpp : 定义 DLL 应用程序的导出函数。 // #include "stdafx.h" #include "MySQL.h" // 构造函数 CMySQL::CMySQL() { m_nErrorID = 0; m_pMySQL = new MYSQL; mysql_init(m_pMySQL); // 初始化MySQL结构 } // 析构函数 CMySQL::~CMySQL() { // 销毁MySQL结构 mysql_close(m_pMySQL); delete m_pMySQL; m_pMySQL = NULL; } // 返回错误描述 string CMySQL::GetErrorDesc(__in int nErrorID) { switch (nErrorID) { case 0: return "执行成功"; case -1: return "参数错误"; case -2: return "无数据"; default: return mysql_error(m_pMySQL); } } // 返回错误ID int CMySQL::GetErrorID() { int nTemp = m_nErrorID; m_nErrorID = 0; return nTemp; } // 连接MySQL数据库 bool CMySQL::Connect(__in string szIpAddr, __in unsigned int unPort, __in string szUser, __in string szPass, __in string szDatabase) { if (szIpAddr.empty() || unPort <= 1024/*1024以下端口是操作系统预留端口,不可占用*/ || szUser.empty() || szPass.empty() || szDatabase.empty()) { m_nErrorID = -1; return false; } // 连接MySQL服务器 if (!mysql_real_connect(m_pMySQL, szIpAddr.c_str(), szUser.c_str(), szPass.c_str(), szDatabase.c_str(), unPort, NULL, 0)) { m_nErrorID = mysql_errno(m_pMySQL); return false; } return true; } // 向数据库发送指令 bool CMySQL::Command(__in string szComm) { if (szComm.empty()){ m_nErrorID = -1; return false; } int nRet = mysql_real_query(m_pMySQL, szComm.c_str(), szComm.length()); if (nRet == 0)return true; else { m_nErrorID = nRet; return false; } } // 接收结果 bool CMySQL::Result(__out string **pOutBuf, __out int *pNum) { if (!pOutBuf || !pNum)// 检查参数 { m_nErrorID = -1; return false; } MYSQL_RES *pRes = mysql_store_result(m_pMySQL); if (!pRes) // 检查结果集 { m_nErrorID = -2; return false; } int nDataNumber = pRes->data->rows;// 有多少条(行)数据 if (nDataNumber < 1) // 检查有没有数据 { m_nErrorID = -2; return false; } string* pszRecvResult = new string[nDataNumber]; MYSQL_ROW row; unsigned int nIndex = 0; while (row = mysql_fetch_row(pRes))// 检索结果集 { int nResultRowNumber = mysql_num_fields(pRes);// 获取结果集的行数 for (int i = 0; i < nResultRowNumber; i++) { pszRecvResult[nIndex] += row[i]; pszRecvResult[nIndex] += " "; } nIndex++; } mysql_free_result(pRes); // 释放结果集 *pOutBuf = pszRecvResult; *pNum = nDataNumber; return true; }
(本人文化水平有限,写得不好还请不要介意!)