C++利用MySQL API连接和操作数据库实例详解

2020-01-06 16:25:58王振洲

C++利用MySQL,API操作数据库,C++利用MSQL,API操作数据库实例详解,C++,MySQL,API操作数据

下面就来设计和实现我们自己的C++访问MySQL数据库的组件。

3.1头文件的设计


//mysqlhelper.h

#ifndef __MYSQL_HELPER_H__
#define __MYSQL_HELPER_H__

#include <stdlib.h>

#include <map>
#include <vector>
#include <string>
using namespace std;

#include <mysql.h>

namespace mysqlhelper
{

/*********************
*@brief 数据库异常类
**********************/
struct MysqlHelper_Exception //: public TC_Exception
{
 MysqlHelper_Exception(const string &sBuffer):errorInfo(sBuffer){}; //: TC_Exception(sBuffer){};
 ~MysqlHelper_Exception() throw(){}; 

 string errorInfo;
};

/***********************
* @brief 数据库配置接口
***********************/
struct DBConf
{

 string _host;//主机地址
 string _user; //用户名 
 string _password;//密码
 string _database; //数据库
 string _charset; //字符集
 int _port;//端口
 int _flag; //客户端标识

 /*****************
 * @brief 构造函数
 *****************/
 DBConf():_port(0), _flag(0){}

 /**********************************
 * @brief 读取数据库配置. 
 * @param mpParam 存放数据库配置的map 
 * dbhost: 主机地址
 * dbuser:用户名
 * dbpass:密码
 * dbname:数据库名称
 * dbport:端口
 **********************************/
 void loadFromMap(const map<string, string> &mpParam)
 {
 map<string, string> mpTmp = mpParam;

 _host = mpTmp["dbhost"];
 _user = mpTmp["dbuser"];
 _password = mpTmp["dbpass"];
 _database = mpTmp["dbname"];
 _charset = mpTmp["charset"];
 _port = atoi(mpTmp["dbport"].c_str());
 _flag = 0;

 if(mpTmp["dbport"] == "")
 {
 _port = 3306;
 }
 }
};

/**************************************************************
* @brief:MySQL数据库操作类 
* @feature:非线程安全,通常一个线程一个MysqlHelper对象;
* 对于insert/update可以有更好的函数封装,保证SQL注入;
* MysqlHelper::DB_INT表示组装sql语句时,不加””和转义;
* MysqlHelper::DB_STR表示组装sql语句时,加””并转义;
**************************************************************/
class MysqlHelper{

public:
 /**
 * @brief 构造函数
 */
 MysqlHelper();

 /**
 * @brief 构造函数. 
 * @param: sHost:主机IP
 * @param sUser 用户
 * @param sPasswd 密码
 * @param sDatebase 数据库
 * @param port 端口
 * @param iUnixSocket socket
 * @param iFlag 客户端标识
 */
 MysqlHelper(const string& sHost, const string& sUser = "", const string& sPasswd = "", const string& sDatabase = "", const string &sCharSet = "", int port = 0, int iFlag = 0);

 /**
 * @brief 构造函数. 
 * @param tcDBConf 数据库配置
 */
 MysqlHelper(const DBConf& tcDBConf);

 /**
 * @brief 析构函数.
 */
 ~MysqlHelper();

 /**
 * @brief 初始化. 
 * 
 * @param sHost 主机IP
 * @param sUser 用户
 * @param sPasswd 密码
 * @param sDatebase 数据库
 * @param port 端口
 * @param iUnixSocket socket
 * @param iFlag 客户端标识
 * @return 无
 */
 void init(const string& sHost, const string& sUser = "", const string& sPasswd = "", const string& sDatabase = "", const string &sCharSet = "", int port = 0, int iFlag = 0);

 /**
 * @brief 初始化. 
 * 
 * @param tcDBConf 数据库配置
 */
 void init(const DBConf& tcDBConf);

 /**
 * @brief 连接数据库. 
 * 
 * @throws MysqlHelper_Exception
 * @return 无
 */
 void connect();

 /**
 * @brief 断开数据库连接. 
 * @return 无
 */
 void disconnect();

 /**
 * @brief 获取数据库变量. 
 * @return 数据库变量
 */
 string getVariables(const string &sName);

 /**
 * @brief 直接获取数据库指针. 
 * 
 * @return MYSQL* 数据库指针
 */
 MYSQL *getMysql();

 /**
 * @brief 字符转义. 
 * 
 * @param sFrom 源字符串
 * @param sTo 输出字符串
 * @return 输出字符串
 */
 string escapeString(const string& sFrom);

 /**
 * @brief 更新或者插入数据. 
 * 
 * @param sSql sql语句
 * @throws MysqlHelper_Exception
 * @return
 */
 void execute(const string& sSql);

 /**
 * @brief mysql的一条记录
 */
 class MysqlRecord
 {
 public:
 /**
 * @brief 构造函数.
 * 
 * @param record
 */
 MysqlRecord(const map<string, string> &record);

 /**
 * @brief 获取数据,s一般是指数据表的某个字段名 
 * @param s 要获取的字段
 * @return 符合查询条件的记录的s字段名
 */
 const string& operator[](const string &s);
 protected:
 const map<string, string> &_record;
 };

 /**
 * @brief 查询出来的mysql数据
 */
 class MysqlData
 {
 public:
 /**
 * @brief 所有数据.
 * 
 * @return vector<map<string,string>>&
 */
 vector<map<string, string> >& data();

 /**
 * 数据的记录条数
 * 
 * @return size_t
 */
 size_t size();

 /**
 * @brief 获取某一条记录. 
 * 
 * @param i 要获取第几条记录 
 * @return MysqlRecord类型的数据,可以根据字段获取相关信息,
 */
 MysqlRecord operator[](size_t i);

 protected:
 vector<map<string, string> > _data;
 };

 /**
 * @brief Query Record. 
 * 
 * @param sSql sql语句
 * @throws MysqlHelper_Exception
 * @return MysqlData类型的数据,可以根据字段获取相关信息
 */
 MysqlData queryRecord(const string& sSql);

 /**
 * @brief 定义字段类型, 
 * DB_INT:数字类型 
 * DB_STR:字符串类型
 */
 enum FT
 {
 DB_INT, 
 DB_STR, 
 };

 /**
 * 数据记录
 */
 typedef map<string, pair<FT, string> > RECORD_DATA;

 /**
 * @brief 更新记录. 
 * 
 * @param sTableName 表名
 * @param mpColumns 列名/值对
 * @param sCondition where子语句,例如:where A = B
 * @throws MysqlHelper_Exception
 * @return size_t 影响的行数
 */
 size_t updateRecord(const string &sTableName, const map<string, pair<FT, string> > &mpColumns, const string &sCondition);

 /**
 * @brief 插入记录. 
 * 
 * @param sTableName 表名
 * @param mpColumns 列名/值对
 * @throws MysqlHelper_Exception
 * @return size_t 影响的行数
 */
 size_t insertRecord(const string &sTableName, const map<string, pair<FT, string> > &mpColumns);

 /**
 * @brief 替换记录. 
 * 
 * @param sTableName 表名
 * @param mpColumns 列名/值对
 * @throws MysqlHelper_Exception
 * @return size_t 影响的行数
 */
 size_t replaceRecord(const string &sTableName, const map<string, pair<FT, string> > &mpColumns);

 /**
 * @brief 删除记录. 
 * 
 * @param sTableName 表名
 * @param sCondition where子语句,例如:where A = B
 * @throws MysqlHelper_Exception
 * @return size_t 影响的行数
 */
 size_t deleteRecord(const string &sTableName, const string &sCondition = "");

 /**
 * @brief 获取Table查询结果的数目. 
 * 
 * @param sTableName 用于查询的表名
 * @param sCondition where子语句,例如:where A = B
 * @throws MysqlHelper_Exception
 * @return size_t 查询的记录数目
 */
 size_t getRecordCount(const string& sTableName, const string &sCondition = "");

 /**
 * @brief 获取Sql返回结果集的个数. 
 * 
 * @param sCondition where子语句,例如:where A = B
 * @throws MysqlHelper_Exception
 * @return 查询的记录数目
 */
 size_t getSqlCount(const string &sCondition = "");

 /**
 * @brief 存在记录. 
 * 
 * @param sql sql语句
 * @throws MysqlHelper_Exception
 * @return 操作是否成功
 */
 bool existRecord(const string& sql);

 /**
 * @brief 获取字段最大值. 
 * 
 * @param sTableName 用于查询的表名
 * @param sFieldName 用于查询的字段
 * @param sCondition where子语句,例如:where A = B
 * @throws MysqlHelper_Exception
 * @return 查询的记录数目
 */
 int getMaxValue(const string& sTableName, const string& sFieldName, const string &sCondition = "");

 /**
 * @brief 获取auto_increment最后插入得ID. 
 * 
 * @return ID值
 */
 long lastInsertID();

 /**
 * @brief 构造Insert-SQL语句. 
 * 
 * @param sTableName 表名
 * @param mpColumns 列名/值对
 * @return string insert-SQL语句
 */
 string buildInsertSQL(const string &sTableName, const map<string, pair<FT, string> > &mpColumns);

 /**
 * @brief 构造Replace-SQL语句. 
 * 
 * @param sTableName 表名
 * @param mpColumns 列名/值对
 * @return string insert-SQL语句
 */
 string buildReplaceSQL(const string &sTableName, const map<string, pair<FT, string> > &mpColumns);

 /**
 * @brief 构造Update-SQL语句. 
 * 
 * @param sTableName 表名
 * @param mpColumns 列名/值对
 * @param sCondition where子语句
 * @return string Update-SQL语句
 */
 string buildUpdateSQL(const string &sTableName,const map<string, pair<FT, string> > &mpColumns, const string &sCondition);

 /**
 * @brief 获取最后执行的SQL语句.
 * 
 * @return SQL语句
 */
 string getLastSQL() { return _sLastSql; }

 /**
 * @brief 获取查询影响数
 * @return int
 */
 size_t getAffectedRows();
protected:
 /**
 * @brief copy contructor,只申明,不定义,保证不被使用 
 */
 MysqlHelper(const MysqlHelper &tcMysql);

 /**
 * 
 * @brief 只申明,不定义,保证不被使用
 */
 MysqlHelper &operator=(const MysqlHelper &tcMysql);


private:

 /**
 * 数据库指针
 */
 MYSQL *_pstMql;

 /**
 * 数据库配置
 */
 DBConf _dbConf;

 /**
 * 是否已经连接
 */
 bool _bConnected;

 /**
 * 最后执行的sql
 */
 string _sLastSql;

};
}
#endif //__MYSQL_HELPER_H__