C++ 利用 MySQL API 连接和操作数据库

1.C++连接和操作MySQL的方式

在Windows平台,我们可以使用ADO、ODBC或者MySQL API进行连接和操作。ADO (ActiveX Data Objects,ActiveX数据对象)是Microsoft提出的应用程序接口(API)用以实现访问关系或非关系数据库中的数据。

ODBC(Open DataBase Connection)开放式系统互连,是一种数据库访问协议,提供了访问数据库的API接口。基于ODBC的应用程序,对数据库操作不依赖于具体的DBMS,不直接与DBMS打交道,所有数据库操作由对应DBMS的ODBC驱动程序完成,即:系统中不需要安装DBMS系统,如SQL SERVER 2005,但必须有SQL SERVER 2005的ODBC驱动程序,然后在ODBC管理器中注册数据源后,就可以在应用程序中通过ODBC API访问该数据库。ODBC数据库访问技术只适用于windows系统,因为需要在ODBC驱动程序管理器中进行数据源注册,而只有windows才集成了ODBC驱动程序管理器(“控制面板/管理工具/数据源”)。

ADO具有跨系统平台特性,它直接对数据库进行操作,即系统中必须有DBMS,但不需要驱动程序,不需要注册数据源,所以具有很好的可移植性。

那么,在Linux平台如何连接和使用MSQL数据库呢?我们同样可以使用ADO、unixODBC或者MySQL API。这里不再赘述前两者的用法,读者可自行研究实践,下文将详细讲解MySQL创建数据库和C++利用MSQL API连接和操作数据库。

2.数据表的设计和创建

了解MySQL支持的数据字段类型对数据库的优化是非常重要的。MySQL支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。

本文以大学熟悉的学生选课管理系统中用到的数据库为例,来实现对数据库的访问。本文数据库的建立,是在Linux平台使用msyql命令完成,关于数据库建立请参考本人的另一篇博文:MySQL数据库的设计和命令行模式下建立详细过程

主要有三张表:学生表,课程表和选课表。下面是数据表的详细情况。

学生表:
这里写图片描述

课程表:
这里写图片描述

选课表:
这里写图片描述

3.数据库的连接和操作

下面将讲解利用MySQL API来编写我们自己的用于访问MySQL的中间件,也是我们自己的组件。我们的组件在应用程序和MySQL数据库之间构成的层次结构如下图所示:
这里写图片描述

下面就来设计和实现我们自己的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__

3.2 源文件实现

// mysqlhelper.cpp

#include "mysqlHelper.h"

#include <string.h>
#include <sstream>

using namespace std;

namespace mysqlhelper{

MysqlHelper::MysqlHelper():_bConnected(false)
{
	_pstMql = mysql_init(NULL);
}

MysqlHelper::MysqlHelper(const string& sHost, const string& sUser, const string& sPasswd, const string& sDatabase, const string &sCharSet, int port, int iFlag)
:_bConnected(false)
{
    init(sHost, sUser, sPasswd, sDatabase, sCharSet, port, iFlag);
    
    _pstMql = mysql_init(NULL);
}

MysqlHelper::MysqlHelper(const DBConf& tcDBConf)
:_bConnected(false)
{
    _dbConf = tcDBConf;
    
    _pstMql = mysql_init(NULL);    
}

MysqlHelper::~MysqlHelper()
{
    if (_pstMql != NULL)
    {
        mysql_close(_pstMql);
        _pstMql = NULL;
    }
}

void MysqlHelper::init(const string& sHost, const string& sUser, const string& sPasswd, const string& sDatabase, const string &sCharSet, int port, int iFlag)
{
    _dbConf._host = sHost;
    _dbConf._user = sUser;
    _dbConf._password = sPasswd;
    _dbConf._database = sDatabase;
    _dbConf._charset  = sCharSet;
    _dbConf._port = port;
    _dbConf._flag = iFlag;
}

void MysqlHelper::init(const DBConf& tcDBConf)
{
    _dbConf = tcDBConf;
}

void MysqlHelper::connect()
{
    disconnect();

    if( _pstMql == NULL)
    {
        _pstMql = mysql_init(NULL);
    }

    //建立连接后, 自动调用设置字符集语句
    if(!_dbConf._charset.empty())  {
        if (mysql_options(_pstMql, MYSQL_SET_CHARSET_NAME, _dbConf._charset.c_str())) {
    		throw MysqlHelper_Exception(string("MysqlHelper::connect: mysql_options MYSQL_SET_CHARSET_NAME ") + _dbConf._charset + ":" + string(mysql_error(_pstMql)));
        }
    }

    if (mysql_real_connect(_pstMql, _dbConf._host.c_str(), _dbConf._user.c_str(), _dbConf._password.c_str(), _dbConf._database.c_str(), _dbConf._port, NULL, _dbConf._flag) == NULL) 
    {
        throw MysqlHelper_Exception("[MysqlHelper::connect]: mysql_real_connect: " + string(mysql_error(_pstMql)));
    }
    
	_bConnected = true;
}

void MysqlHelper::disconnect()
{
    if (_pstMql != NULL)
    {
        mysql_close(_pstMql);
        _pstMql = mysql_init(NULL);
    }
    
	_bConnected = false;    
}

string MysqlHelper::escapeString(const string& sFrom)
{
	if(!_bConnected)
	{
		connect();
	}

    string sTo;
    string::size_type iLen = sFrom.length() * 2 + 1;
    char *pTo = (char *)malloc(iLen);

    memset(pTo, 0x00, iLen);
    
    mysql_real_escape_string(_pstMql, pTo, sFrom.c_str(), sFrom.length());

    sTo = pTo;

    free(pTo);

    return sTo;
}

MYSQL *MysqlHelper::getMysql(void)
{
    return _pstMql;
}

string MysqlHelper::buildInsertSQL(const string &sTableName, const RECORD_DATA &mpColumns)
{
    ostringstream sColumnNames;
    ostringstream sColumnValues;
    
    map<string, pair<FT, string> >::const_iterator itEnd = mpColumns.end();

    for(map<string, pair<FT, string> >::const_iterator it = mpColumns.begin(); it != itEnd; ++it)
    {
        if (it == mpColumns.begin())
        {
            sColumnNames << "`" << it->first << "`";
            if(it->second.first == DB_INT)
            {
                sColumnValues << it->second.second;
            }
            else
            {
                sColumnValues << "'" << escapeString(it->second.second) << "'";
            }
        }
        else
        {
            sColumnNames << ",`" << it->first << "`";
            if(it->second.first == DB_INT)
            {
                sColumnValues << "," + it->second.second;
            }
            else
            {
                sColumnValues << ",'" + escapeString(it->second.second) << "'";
            }
        }
    }

    ostringstream os;
    os << "insert into " << sTableName << " (" << sColumnNames.str() << ") values (" << sColumnValues.str() << ")";
    return os.str();
}

string MysqlHelper::buildReplaceSQL(const string &sTableName, const RECORD_DATA &mpColumns)
{
    ostringstream sColumnNames;
    ostringstream sColumnValues;

    map<string, pair<FT, string> >::const_iterator itEnd = mpColumns.end();
    for(map<string, pair<FT, string> >::const_iterator it = mpColumns.begin(); it != itEnd; ++it)
    {
        if (it == mpColumns.begin())
        {
            sColumnNames << "`" << it->first << "`";
            if(it->second.first == DB_INT)
            {
                sColumnValues << it->second.second;
            }
            else
            {
                sColumnValues << "'" << escapeString(it->second.second) << "'";
            }
        }
        else
        {
            sColumnNames << ",`" << it->first << "`";
            if(it->second.first == DB_INT)
            {
                sColumnValues << "," + it->second.second;
            }
            else
            {
                sColumnValues << ",'" << escapeString(it->second.second) << "'";
            }
        }
    }

    ostringstream os;
    os << "replace into " << sTableName << " (" << sColumnNames.str() << ") values (" << sColumnValues.str() << ")";
    return os.str();
}

string MysqlHelper::buildUpdateSQL(const string &sTableName,const RECORD_DATA &mpColumns, const string &sWhereFilter)
{
    ostringstream sColumnNameValueSet;

    map<string, pair<FT, string> >::const_iterator itEnd = mpColumns.end();

    for(map<string, pair<FT, string> >::const_iterator it = mpColumns.begin(); it != itEnd; ++it)
    {
        if (it == mpColumns.begin())
        {
            sColumnNameValueSet << "`" << it->first << "`";
        }
        else
        {
            sColumnNameValueSet << ",`" << it->first << "`";
        }

        if(it->second.first == DB_INT)
        {
            sColumnNameValueSet << "= " << it->second.second;
        }
        else
        {
            sColumnNameValueSet << "= '" << escapeString(it->second.second) << "'";
        }
    }

    ostringstream os;
    os << "update " << sTableName << " set " << sColumnNameValueSet.str() << " " << sWhereFilter;

    return os.str();
}

string MysqlHelper::getVariables(const string &sName)
{
    string sql = "SHOW VARIABLES LIKE '" + sName + "'";

    MysqlData data = queryRecord(sql);
    if(data.size() == 0)
    {
        return "";
    }

    if(sName == data[0]["Variable_name"])
    {
        return data[0]["Value"];
    }

    return "";
}

void MysqlHelper::execute(const string& sSql)
{
	/**
	没有连上, 连接数据库
	*/
	if(!_bConnected)
	{
		connect();
	}

    _sLastSql = sSql;

    int iRet = mysql_real_query(_pstMql, sSql.c_str(), sSql.length());
    if(iRet != 0)
    {
        /**
        自动重新连接
        */
		int iErrno = mysql_errno(_pstMql);
		if (iErrno == 2013 || iErrno == 2006)
        {
            connect();
            iRet = mysql_real_query(_pstMql, sSql.c_str(), sSql.length());
        }
    }

    if (iRet != 0)
    {
        throw MysqlHelper_Exception("[MysqlHelper::execute]: mysql_query: [ " + sSql+" ] :" + string(mysql_error(_pstMql)));	
    }
}

MysqlHelper::MysqlData MysqlHelper::queryRecord(const string& sSql)
{
    MysqlData   data;

	/**
	没有连上, 连接数据库
	*/
	if(!_bConnected)
	{
		connect();
	}

    _sLastSql = sSql;

    int iRet = mysql_real_query(_pstMql, sSql.c_str(), sSql.length());
    if(iRet != 0)
    {
        /**
        自动重新连接
        */
		int iErrno = mysql_errno(_pstMql);
		if (iErrno == 2013 || iErrno == 2006)
        {
            connect();
            iRet = mysql_real_query(_pstMql, sSql.c_str(), sSql.length());
        }
    }

    if (iRet != 0)
    {
        throw MysqlHelper_Exception("[MysqlHelper::execute]: mysql_query: [ " + sSql+" ] :" + string(mysql_error(_pstMql)));	
    }
    
    MYSQL_RES *pstRes = mysql_store_result(_pstMql);

    if(pstRes == NULL)
    {
        throw MysqlHelper_Exception("[MysqlHelper::queryRecord]: mysql_store_result: " + sSql + " : " + string(mysql_error(_pstMql)));
    }
    
    vector<string> vtFields;
    MYSQL_FIELD *field;
    while((field = mysql_fetch_field(pstRes)))
    {
         vtFields.push_back(field->name);
    }

    map<string, string> mpRow;
    MYSQL_ROW stRow;
    
    while((stRow = mysql_fetch_row(pstRes)) != (MYSQL_ROW)NULL)
    {
        mpRow.clear();
        unsigned long * lengths = mysql_fetch_lengths(pstRes);
        for(size_t i = 0; i < vtFields.size(); i++)
        {
            if(stRow[i])
            {
                mpRow[vtFields[i]] = string(stRow[i], lengths[i]);
            }
            else
            {
                mpRow[vtFields[i]] = "";
            }
        }

        data.data().push_back(mpRow);
    }

    mysql_free_result(pstRes);

    return data;
}

size_t MysqlHelper::updateRecord(const string &sTableName, const RECORD_DATA &mpColumns, const string &sCondition)
{
    string sSql = buildUpdateSQL(sTableName, mpColumns, sCondition);
    execute(sSql);

    return mysql_affected_rows(_pstMql);
}

size_t MysqlHelper::insertRecord(const string &sTableName, const RECORD_DATA &mpColumns)
{
    string sSql = buildInsertSQL(sTableName, mpColumns);
    execute(sSql);

    return mysql_affected_rows(_pstMql);
}

size_t MysqlHelper::replaceRecord(const string &sTableName, const RECORD_DATA &mpColumns)
{
    string sSql = buildReplaceSQL(sTableName, mpColumns);
    execute(sSql);

    return mysql_affected_rows(_pstMql);
}

size_t MysqlHelper::deleteRecord(const string &sTableName, const string &sCondition)
{
    ostringstream sSql;
    sSql << "delete from " << sTableName << " " << sCondition;

    execute(sSql.str());

    return mysql_affected_rows(_pstMql);
}

size_t MysqlHelper::getRecordCount(const string& sTableName, const string &sCondition)
{
    ostringstream sSql;
    sSql << "select count(*) as num from " << sTableName << " " << sCondition;

    MysqlData data = queryRecord(sSql.str());

	long n = atol(data[0]["num"].c_str());

	return n;

}

size_t MysqlHelper::getSqlCount(const string &sCondition)
{
    ostringstream sSql;
    sSql << "select count(*) as num " << sCondition;

    MysqlData data = queryRecord(sSql.str());

	long n = atol(data[0]["num"].c_str());

    return n;
}

int MysqlHelper::getMaxValue(const string& sTableName, const string& sFieldName,const string &sCondition)
{
    ostringstream sSql;
    sSql << "select " << sFieldName << " as f from " << sTableName << " " << sCondition << " order by f desc limit 1";

    MysqlData data = queryRecord(sSql.str());

	int n = 0;
    
    if(data.size() == 0)
    {
        n = 0;
    }
    else
    {
        n = atol(data[0]["f"].c_str());
    }

	return n;
}

bool MysqlHelper::existRecord(const string& sql)
{
    return queryRecord(sql).size() > 0;
}

long MysqlHelper::lastInsertID()
{
    return mysql_insert_id(_pstMql);
}

size_t MysqlHelper::getAffectedRows()
{
	return mysql_affected_rows(_pstMql);
}

//
MysqlHelper::MysqlRecord::MysqlRecord(const map<string, string> &record):_record(record){}

const string& MysqlHelper::MysqlRecord::operator[](const string &s)
{
    map<string, string>::const_iterator it = _record.find(s);
    if(it == _record.end())
    {
        throw MysqlHelper_Exception("field '" + s + "' not exists.");
    }
    return it->second;
}

//

vector<map<string, string> >& MysqlHelper::MysqlData::data()
{
    return _data;
}

size_t MysqlHelper::MysqlData::size()
{
    return _data.size();
}

MysqlHelper::MysqlRecord MysqlHelper::MysqlData::operator[](size_t i)
{
    return MysqlRecord(_data[i]);
}

}//end namespace 

3.3 使用 demo

/****************************************************
*@brief:mysqlhelper demo
*@autor:lvlv
*@date:2016.06.12
*@MySQL version:MySQL Community Server 5.6.30 (GPL)
****************************************************/

#include <string.h>
#include <iostream>
#include <string>
using namespace std;

#include "mysqlHelper.h"
using namespace mysqlhelper;


int main(int argc,char* argv[]){
	
	//初始化mysql对象并建立连接
	MysqlHelper mysqlHelper;
	mysqlHelper.init("119.29.184.114","root","123456","StudentCourse");
	try{
		mysqlHelper.connect();
	}catch(MysqlHelper_Exception& excep){
		cout<<excep.errorInfo;
		return -1;
	}
	
	//增加一条学生记录
	//示例插入语句
	//string sql="insert into student values("201421031060","吕吕","华南理工大学","2014","软件工程",1)";
	
	MysqlHelper::RECORD_DATA record;
	record.insert(make_pair("studentNo",make_pair(MysqlHelper::DB_STR,"201421031060")));
	record.insert(make_pair("name",make_pair(MysqlHelper::DB_STR,"吕吕")));
	record.insert(make_pair("school",make_pair(MysqlHelper::DB_STR,"广州中医药大学")));
	record.insert(make_pair("grade",make_pair(MysqlHelper::DB_STR,"2014")));
	record.insert(make_pair("major",make_pair(MysqlHelper::DB_STR,"计算机科学与技术")));
	record.insert(make_pair("gender",make_pair(MysqlHelper::DB_INT,"1")));
	   int res=0;
	try{
		res=mysqlHelper.insertRecord("student",record);
	}catch(MysqlHelper_Exception& excep){
		cout<<excep.errorInfo;
		return -1;
	}
	cout<<"res:"<<res<<" insert successfully "<<endl;
	
	//删除一条学生记录,学号为201421031059
	try{
		res=mysqlHelper.deleteRecord("student","where studentNo=\"201421031059\"");
	}catch(MysqlHelper_Exception& excep){
		cout<<excep.errorInfo;
		return -1;
	}
	cout<<"res:"<<res<<" delete successfully "<<endl;
	
	//查找学号为201421031059的学生选择的所有课程名称
	MysqlHelper::MysqlData dataSet;
	string querySQL="select courseName from course co where co.courseNo in (select courseNo from courseSelection where studentNo=\"201421031060\")";
	try{
		dataSet=mysqlHelper.queryRecord(querySQL);
	}catch(MysqlHelper_Exception& excep){
		cout<<excep.errorInfo;
		return -1;
	}
	cout<<"query successfully"<<endl;
	for(size_t i=0;i<dataSet.size();++i){
		cout<<dataSet[i]["courseName"]<<endl;
	}
	
	//修改学号为201421031060的学生专业
	MysqlHelper::RECORD_DATA recordChange;
	recordChange.insert(make_pair("major",make_pair(MysqlHelper::DB_STR,"软件工程")));
	try{
		res=mysqlHelper.updateRecord("student",recordChange,"where studentNo=\"201421031060\"");
	}catch(MysqlHelper_Exception& excep){
		cout<<excep.errorInfo;
		return -1;
	}
	cout<<"res:"<<res<<" update successfully"<<endl;
	
	return 0;
}

3.4 Makefile

##################################
# @brief:make scripts
# @date:2016.05.28
# @author:lvlv
##################################

#environment var
VPATH+=.

CC:=g++
FLAGS=-g -Wall -std=c++11
INC+=-I/usr/local/mysql/include
LIBDIR+=-L/usr/local/mysql/lib

CPPDIRS=.
CPPS=$(shell for dir in ${CPPDIRS};do echo $${dir}/*.cpp;done)

OBJDIR=obj
OBJS=$(patsubst %.cpp,${OBJDIR}/%.o,$(notdir ${CPPS}))

TARGET:=mysqlDemo.out

${TARGET}:${OBJS}
	${CC} ${FLAGS} ${OBJS} -o $@ ${LIBDIR} -lmysqlclient
	
${OBJDIR}/%.o:./%.cpp
	${CC} ${FLAGS} ${INC} -o $@ -c $<

.PHONY:clean
clean:
	rm -f ${TARGET} ${OBJDIR}/*
  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值