C++利用MySQL API連接和操作數(shù)據(jù)庫實(shí)例詳解
1.C++連接和操作MySQL的方式
系列文章:
C++利用MySQL API連接和操作數(shù)據(jù)庫實(shí)例詳解
在Windows平臺(tái),我們可以使用ADO、ODBC或者M(jìn)ySQL API進(jìn)行連接和操作。ADO (ActiveX Data Objects,ActiveX數(shù)據(jù)對象)是Microsoft提出的一個(gè)用于存取數(shù)據(jù)源的COM組件。它提供了程序語言和統(tǒng)一數(shù)據(jù)訪問方式OLE DB的一個(gè)中間層,也就是Microsoft提出的應(yīng)用程序接口(API)用以實(shí)現(xiàn)訪問關(guān)系或非關(guān)系數(shù)據(jù)庫中的數(shù)據(jù)。
ODBC(Open DataBase Connection)開放式系統(tǒng)互連,是一種數(shù)據(jù)庫訪問協(xié)議,提供了訪問數(shù)據(jù)庫的API接口?;贠DBC的應(yīng)用程序,對數(shù)據(jù)庫操作不依賴于具體的DBMS,不直接與DBMS打交道,所有數(shù)據(jù)庫操作由對應(yīng)DBMS的ODBC驅(qū)動(dòng)程序完成,即:系統(tǒng)中不需要安裝DBMS系統(tǒng),如SQL SERVER 2005,但必須有SQL SERVER 2005的ODBC驅(qū)動(dòng)程序,然后在ODBC管理器中注冊數(shù)據(jù)源后,就可以在應(yīng)用程序中通過ODBC API訪問該數(shù)據(jù)庫。ODBC數(shù)據(jù)庫訪問技術(shù)只適用于windows系統(tǒng),因?yàn)樾枰贠DBC驅(qū)動(dòng)程序管理器中進(jìn)行數(shù)據(jù)源注冊,而只有windows才集成了ODBC驅(qū)動(dòng)程序管理器(“控制面板/管理工具/數(shù)據(jù)源”)。
ADO具有跨系統(tǒng)平臺(tái)特性,它直接對DBMS數(shù)據(jù)庫進(jìn)行操作,即系統(tǒng)中必須有DBMS,但不需要驅(qū)動(dòng)程序,不需要注冊數(shù)據(jù)源,所以具有很好的可移植性。
那么,在Linux平臺(tái)如何連接和使用MSQL數(shù)據(jù)庫呢?我們同樣可以使用ADO、unixODBC或者M(jìn)ySQL API。這里不再贅述前兩者的用法,讀者可自行研究實(shí)踐,下文將詳細(xì)講解MySQL創(chuàng)建數(shù)據(jù)庫和C++利用MSQL API連接和操作數(shù)據(jù)庫。
2.MSQL數(shù)據(jù)庫的設(shè)計(jì)和建立
MySQL數(shù)據(jù)庫管理系統(tǒng)(DBMS)中,包含的MySQL中定義數(shù)據(jù)字段的類型對你數(shù)據(jù)庫的優(yōu)化是非常重要的。MySQL支持多種類型,大致可以分為三類:數(shù)值、日期/時(shí)間和字符串(字符)類型。
本文以大學(xué)熟悉的學(xué)生選課管理系統(tǒng)中用到的數(shù)據(jù)庫為例,來實(shí)現(xiàn)對數(shù)據(jù)庫的訪問。本文數(shù)據(jù)庫的建立,是在Linux平臺(tái)使用msyql命令完成
主要有三張表:學(xué)生表,課程表和選課表。下面是數(shù)據(jù)表的詳細(xì)情況。
學(xué)生表:

課程表:

選課表:

3.MSQL數(shù)據(jù)庫的連接和操作
下面將講解利用MySQL API來編寫我們自己的用于訪問MySQL的中間件,也是我們自己的組件。我們的組件在應(yīng)用程序和MySQL數(shù)據(jù)庫之間構(gòu)成的層次結(jié)構(gòu)如下圖所示:

下面就來設(shè)計(jì)和實(shí)現(xiàn)我們自己的C++訪問MySQL數(shù)據(jù)庫的組件。
3.1頭文件的設(shè)計(jì)
//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 數(shù)據(jù)庫異常類
**********************/
struct MysqlHelper_Exception //: public TC_Exception
{
MysqlHelper_Exception(const string &sBuffer):errorInfo(sBuffer){}; //: TC_Exception(sBuffer){};
~MysqlHelper_Exception() throw(){};
string errorInfo;
};
/***********************
* @brief 數(shù)據(jù)庫配置接口
***********************/
struct DBConf
{
string _host;//主機(jī)地址
string _user; //用戶名
string _password;//密碼
string _database; //數(shù)據(jù)庫
string _charset; //字符集
int _port;//端口
int _flag; //客戶端標(biāo)識
/*****************
* @brief 構(gòu)造函數(shù)
*****************/
DBConf():_port(0), _flag(0){}
/**********************************
* @brief 讀取數(shù)據(jù)庫配置.
* @param mpParam 存放數(shù)據(jù)庫配置的map
* dbhost: 主機(jī)地址
* dbuser:用戶名
* dbpass:密碼
* dbname:數(shù)據(jù)庫名稱
* 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數(shù)據(jù)庫操作類
* @feature:非線程安全,通常一個(gè)線程一個(gè)MysqlHelper對象;
* 對于insert/update可以有更好的函數(shù)封裝,保證SQL注入;
* MysqlHelper::DB_INT表示組裝sql語句時(shí),不加””和轉(zhuǎn)義;
* MysqlHelper::DB_STR表示組裝sql語句時(shí),加””并轉(zhuǎn)義;
**************************************************************/
class MysqlHelper{
public:
/**
* @brief 構(gòu)造函數(shù)
*/
MysqlHelper();
/**
* @brief 構(gòu)造函數(shù).
* @param: sHost:主機(jī)IP
* @param sUser 用戶
* @param sPasswd 密碼
* @param sDatebase 數(shù)據(jù)庫
* @param port 端口
* @param iUnixSocket socket
* @param iFlag 客戶端標(biāo)識
*/
MysqlHelper(const string& sHost, const string& sUser = "", const string& sPasswd = "", const string& sDatabase = "", const string &sCharSet = "", int port = 0, int iFlag = 0);
/**
* @brief 構(gòu)造函數(shù).
* @param tcDBConf 數(shù)據(jù)庫配置
*/
MysqlHelper(const DBConf& tcDBConf);
/**
* @brief 析構(gòu)函數(shù).
*/
~MysqlHelper();
/**
* @brief 初始化.
*
* @param sHost 主機(jī)IP
* @param sUser 用戶
* @param sPasswd 密碼
* @param sDatebase 數(shù)據(jù)庫
* @param port 端口
* @param iUnixSocket socket
* @param iFlag 客戶端標(biāo)識
* @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 數(shù)據(jù)庫配置
*/
void init(const DBConf& tcDBConf);
/**
* @brief 連接數(shù)據(jù)庫.
*
* @throws MysqlHelper_Exception
* @return 無
*/
void connect();
/**
* @brief 斷開數(shù)據(jù)庫連接.
* @return 無
*/
void disconnect();
/**
* @brief 獲取數(shù)據(jù)庫變量.
* @return 數(shù)據(jù)庫變量
*/
string getVariables(const string &sName);
/**
* @brief 直接獲取數(shù)據(jù)庫指針.
*
* @return MYSQL* 數(shù)據(jù)庫指針
*/
MYSQL *getMysql();
/**
* @brief 字符轉(zhuǎn)義.
*
* @param sFrom 源字符串
* @param sTo 輸出字符串
* @return 輸出字符串
*/
string escapeString(const string& sFrom);
/**
* @brief 更新或者插入數(shù)據(jù).
*
* @param sSql sql語句
* @throws MysqlHelper_Exception
* @return
*/
void execute(const string& sSql);
/**
* @brief mysql的一條記錄
*/
class MysqlRecord
{
public:
/**
* @brief 構(gòu)造函數(shù).
*
* @param record
*/
MysqlRecord(const map<string, string> &record);
/**
* @brief 獲取數(shù)據(jù),s一般是指數(shù)據(jù)表的某個(gè)字段名
* @param s 要獲取的字段
* @return 符合查詢條件的記錄的s字段名
*/
const string& operator[](const string &s);
protected:
const map<string, string> &_record;
};
/**
* @brief 查詢出來的mysql數(shù)據(jù)
*/
class MysqlData
{
public:
/**
* @brief 所有數(shù)據(jù).
*
* @return vector<map<string,string>>&
*/
vector<map<string, string> >& data();
/**
* 數(shù)據(jù)的記錄條數(shù)
*
* @return size_t
*/
size_t size();
/**
* @brief 獲取某一條記錄.
*
* @param i 要獲取第幾條記錄
* @return MysqlRecord類型的數(shù)據(jù),可以根據(jù)字段獲取相關(guān)信息,
*/
MysqlRecord operator[](size_t i);
protected:
vector<map<string, string> > _data;
};
/**
* @brief Query Record.
*
* @param sSql sql語句
* @throws MysqlHelper_Exception
* @return MysqlData類型的數(shù)據(jù),可以根據(jù)字段獲取相關(guān)信息
*/
MysqlData queryRecord(const string& sSql);
/**
* @brief 定義字段類型,
* DB_INT:數(shù)字類型
* DB_STR:字符串類型
*/
enum FT
{
DB_INT,
DB_STR,
};
/**
* 數(shù)據(jù)記錄
*/
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 影響的行數(shù)
*/
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 影響的行數(shù)
*/
size_t insertRecord(const string &sTableName, const map<string, pair<FT, string> > &mpColumns);
/**
* @brief 替換記錄.
*
* @param sTableName 表名
* @param mpColumns 列名/值對
* @throws MysqlHelper_Exception
* @return size_t 影響的行數(shù)
*/
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 影響的行數(shù)
*/
size_t deleteRecord(const string &sTableName, const string &sCondition = "");
/**
* @brief 獲取Table查詢結(jié)果的數(shù)目.
*
* @param sTableName 用于查詢的表名
* @param sCondition where子語句,例如:where A = B
* @throws MysqlHelper_Exception
* @return size_t 查詢的記錄數(shù)目
*/
size_t getRecordCount(const string& sTableName, const string &sCondition = "");
/**
* @brief 獲取Sql返回結(jié)果集的個(gè)數(shù).
*
* @param sCondition where子語句,例如:where A = B
* @throws MysqlHelper_Exception
* @return 查詢的記錄數(shù)目
*/
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 查詢的記錄數(shù)目
*/
int getMaxValue(const string& sTableName, const string& sFieldName, const string &sCondition = "");
/**
* @brief 獲取auto_increment最后插入得ID.
*
* @return ID值
*/
long lastInsertID();
/**
* @brief 構(gòu)造Insert-SQL語句.
*
* @param sTableName 表名
* @param mpColumns 列名/值對
* @return string insert-SQL語句
*/
string buildInsertSQL(const string &sTableName, const map<string, pair<FT, string> > &mpColumns);
/**
* @brief 構(gòu)造Replace-SQL語句.
*
* @param sTableName 表名
* @param mpColumns 列名/值對
* @return string insert-SQL語句
*/
string buildReplaceSQL(const string &sTableName, const map<string, pair<FT, string> > &mpColumns);
/**
* @brief 構(gòu)造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 獲取最后執(zhí)行的SQL語句.
*
* @return SQL語句
*/
string getLastSQL() { return _sLastSql; }
/**
* @brief 獲取查詢影響數(shù)
* @return int
*/
size_t getAffectedRows();
protected:
/**
* @brief copy contructor,只申明,不定義,保證不被使用
*/
MysqlHelper(const MysqlHelper &tcMysql);
/**
*
* @brief 只申明,不定義,保證不被使用
*/
MysqlHelper &operator=(const MysqlHelper &tcMysql);
private:
/**
* 數(shù)據(jù)庫指針
*/
MYSQL *_pstMql;
/**
* 數(shù)據(jù)庫配置
*/
DBConf _dbConf;
/**
* 是否已經(jīng)連接
*/
bool _bConnected;
/**
* 最后執(zhí)行的sql
*/
string _sLastSql;
};
}
#endif //__MYSQL_HELPER_H__
3.2源文件具體實(shí)現(xiàn)
//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);
}
//建立連接后, 自動(dòng)調(diào)用設(shè)置字符集語句
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)
{
/**
沒有連上, 連接數(shù)據(jù)庫
*/
if(!_bConnected)
{
connect();
}
_sLastSql = sSql;
int iRet = mysql_real_query(_pstMql, sSql.c_str(), sSql.length());
if(iRet != 0)
{
/**
自動(dòng)重新連接
*/
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;
/**
沒有連上, 連接數(shù)據(jù)庫
*/
if(!_bConnected)
{
connect();
}
_sLastSql = sSql;
int iRet = mysql_real_query(_pstMql, sSql.c_str(), sSql.length());
if(iRet != 0)
{
/**
自動(dòng)重新連接
*/
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;
}
//增加一條學(xué)生記錄
//示例插入語句
//string sql="insert into student values("201421031060","呂呂","華南理工大學(xué)","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,"廣州中醫(yī)藥大學(xué)")));
record.insert(make_pair("grade",make_pair(MysqlHelper::DB_STR,"2014")));
record.insert(make_pair("major",make_pair(MysqlHelper::DB_STR,"計(jì)算機(jī)科學(xué)與技術(shù)")));
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;
//刪除一條學(xué)生記錄,學(xué)號為201421031059
try{
res=mysqlHelper.deleteRecord("student","where studentNo=\"201421031059\"");
}catch(MysqlHelper_Exception& excep){
cout<<excep.errorInfo;
return -1;
}
cout<<"res:"<<res<<" delete successfully "<<endl;
//查找學(xué)號為201421031059的學(xué)生選擇的所有課程名稱
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;
}
//修改學(xué)號為201421031060的學(xué)生專業(yè)
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.4makefile
##################################
# @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}/*
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
相關(guān)文章
基于實(shí)現(xiàn)Qt秒表設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了基于實(shí)現(xiàn)Qt秒表設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08
適合初學(xué)者練習(xí)的C語言實(shí)現(xiàn)三子棋小游戲
今天這篇文章主要介紹給大家分享一個(gè)適合初學(xué)者練習(xí)的利用C語言寫三子棋小游戲,用簡單的C語言來實(shí)現(xiàn)小時(shí)候玩的三子棋游戲,下面是人機(jī)對戰(zhàn),當(dāng)然這個(gè)代碼的電腦對手是人工智障而不是人工智能 詳細(xì)內(nèi)容就請跟小編一起來閱讀下面文章內(nèi)容吧2021-10-10
C語言實(shí)現(xiàn)簡單學(xué)生學(xué)籍管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)簡單學(xué)生學(xué)籍管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01

