首页 > 程序人生 > MySql C API 封装

MySql C API 封装

毕设的项目中,需要用到Mysql,于是把MySql的C API进行了简单的封装,以方便使用,目前只对Insert, Delete, Select, Update进行了封装,其它的操作可以直接在下面的封装的基础上进行扩展,这个做起来应该是十分容易的事。下面是封装的代码:

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#ifndef __DB_CLIENT_H__
#define __DB_CLIENT_H__
 
#include <mysql .h>
#include <stdlib .h>
 
/**
 * @brief enumaration for sql cmd type
 */
enum Cmd
{
	CMD_SELECT,
	CMD_INSERT,
	CMD_DELETE,
	CMD_UPDATE
};
/**
 * @brief this is a class for operating the mysql database
 */
class DBClient
{
public:
	DBClient():
	  m_usDBPort(0),
	  m_pResultSet(NULL)
	{
		memset(m_szDBIP, 0, sizeof(m_szDBIP));
		memset(m_szUserName, 0, sizeof(m_szUserName));
		memset(m_szPassword, 0, sizeof(m_szPassword));
		memset(m_szDBName, 0, sizeof(m_szDBName));
	}
        ~DBClient()
	{
		FreeResultSet();
		mysql_close(&m_oDBHandle);
	}
	/**
	 * @brief initialize the db connection info
	 * @param pDBIP, the db ip address
	 * @param usDBPort, the db port
	 * @param pDBName, the db name
	 * @param pUserName, the db username
	 * @param pPassword, the db password
	 * @return true if init success, otherwise, false
	 */
	bool Init(const char * pDBIP, unsigned short usDBPort,
	          const char * pDBName, const char * pUserName, 
		  const char * pPassword);
	/**
	 * @brief connect the db server
	 * @return true if connect success, otherwise, false
	 */
	bool Connect();
	/**
	 * @brief execute the sql statement
	 * @param pSqlStr, the sql statement pointer
	 * @return true if execute success, otherwise, false
	 */
	bool Execute(const char * pSqlStr, Cmd eCmd);
	/**
	 * @brief get the next result of the operation
	 * @param pRes, the result row
	 * @param pLen, the array of the length of every fields
	 * @param nNum, the num of fields
	 * @return true if get the next result success, otherwise, false
	 */
	bool GetNextResult(char **& pRes, unsigned long *& pLen, 
		           int & nNum);
	/**
	 * @brief get the most recent error No.
	 */
	unsigned int GetErrorNo()
	{
		return mysql_errno(&m_oDBHandle);
	}
private:
	/**
	 * @brief free the memory of the result set
	 */
	void FreeResultSet();
private:
	/*db ip address*/
	char m_szDBIP[MAX_IP_LEN];
	/*db port*/
	unsigned short m_usDBPort;
	/*db name*/
	char m_szDBName[MAX_DB_NAME_LEN];
	/*db username*/
	char m_szUserName[MAX_USER_NAME_LEN];
	/*db user's password*/
	char m_szPassword[MAX_PASSWD_LEN];
	/*the db connection handle object*/
	MYSQL m_oDBHandle;
	/*the pointer of result set for operating's result*/
	MYSQL_RES * m_pResultSet;
};
#endif // __DB_CLIENT_H__
</stdlib></mysql>
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include "DBClient.h"
#include <string .h>
 
#pragma comment(lib, "libmysql.lib")
 
bool DBClient::Init(const char * pDBIP, unsigned short usDBPort,
	            const char * pDBName, const char * pUserName,
	            const char * pPassword)
{
	strcpy(m_szDBIP, pDBIP);
	m_usDBPort = usDBPort;
	strcpy(m_szDBName, pDBName);
	strcpy(m_szUserName, pUserName);
	strcpy(m_szPassword, pPassword);
	if (NULL == mysql_init(&m_oDBHandle))
	{
		return false;
	}
	return true;
}
 
bool DBClient::Connect()
{
	if (NULL == mysql_real_connect(&m_oDBHandle, m_szDBIP,
				       m_szUserName, m_szPassword,
				       m_szDBName, m_usDBPort,
				       NULL, 0))
	{
		return false;
	}
	return true;
}
 
bool DBClient::Execute(const char * pSqlStr, Cmd eCmd)
{
	if (0 != mysql_query(&m_oDBHandle, pSqlStr))
	{
		return false;
	}
	if (CMD_SELECT == eCmd)
	{
		FreeResultSet();
		if (NULL == (m_pResultSet = mysql_store_result(&m_oDBHandle)))
		{
			return false;
		}
	}
	return true;
}
 
bool DBClient::GetNextResult(char **& pRes, unsigned long *& pLen, 
			     int & nNum)
{	
	MYSQL_ROW pRow = mysql_fetch_row(m_pResultSet);
	if(NULL == pRow)
	{
		return false;
	}
	pRes = pRow;
	nNum = mysql_num_fields(m_pResultSet);
	pLen = mysql_fetch_lengths(m_pResultSet);
	return true;
}
 
void DBClient::FreeResultSet()
{
	if (NULL != m_pResultSet)
	{
		mysql_free_result(m_pResultSet);
	}
	m_pResultSet = NULL;
}
</string>

要使用上面的代码,需要注意以下几点:
1.自己定义MAX_IP_LEN, MAX_DB_NAME_LEN, MAX_USER_NAME_LEN, MAX_PASSWD_LEN这几个宏
2.安装MySql的时候,选择安装相关的头文件和库

分类: 程序人生 标签: , ,
  1. MySQL&C++ newbie
    2009年6月8日15:28 | #1

    作者您好!很欣赏你的代码。

    鄙人想请教如何正确封装MySQL C API的预处理语句部分?我把MySQL以及其预处理相关的数据成员,均定义为数据库操作类的私有成员,并把 PreparedStatement parameters及PreparedStatement arguments 定义为 char * * 类型,欲得到最大的灵活度,动态确定参数的个数,只是一直没有成功。若您已实现预处理的C++封装,能否贴上代码,指点迷津。

    谢谢。

    • 2009年6月8日16:40 | #2

      你好,目前我还没有把预处理部分封装起来,在后续工作中,有空的话,我会将预处理部分进行封装的。
      其实,我觉得有了我上面的封装的例子,你可以用类似的方式自己尝试一下,比如数据成员用MYSQL_STMT和MYSQL_BIND,然后定义一个Init函数来初始化这两个数据成员,然后再用MySql提供的C API来实现你要的操作,这样不就OK了吗?Just try it, believe yourself, you can do it!

  1. 本文目前尚无任何 trackbacks 和 pingbacks.
您必须在 登录 后才能发布评论.