1.C++連接和操作MySQL的方式
成都創(chuàng)新互聯(lián)一直秉承“誠(chéng)信做人,踏實(shí)做事”的原則,不欺瞞客戶,是我們最起碼的底線! 以服務(wù)為基礎(chǔ),以質(zhì)量求生存,以技術(shù)求發(fā)展,成交一個(gè)客戶多一個(gè)朋友!為您提供成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、外貿(mào)網(wǎng)站建設(shè)、成都網(wǎng)頁(yè)設(shè)計(jì)、重慶小程序開(kāi)發(fā)、成都網(wǎng)站開(kāi)發(fā)、成都網(wǎng)站制作、成都軟件開(kāi)發(fā)、App定制開(kāi)發(fā)是成都本地專(zhuān)業(yè)的網(wǎng)站建設(shè)和網(wǎng)站設(shè)計(jì)公司,等你一起來(lái)見(jiàn)證!
系列文章:
MySQL 設(shè)計(jì)和命令行模式下建立詳解
C++利用MySQL API連接和操作數(shù)據(jù)庫(kù)實(shí)例詳解
在Windows平臺(tái),我們可以使用ADO、ODBC或者M(jìn)ySQL API進(jìn)行連接和操作。ADO (ActiveX Data Objects,ActiveX數(shù)據(jù)對(duì)象)是Microsoft提出的一個(gè)用于存取數(shù)據(jù)源的COM組件。它提供了程序語(yǔ)言和統(tǒng)一數(shù)據(jù)訪問(wèn)方式OLE DB的一個(gè)中間層,也就是Microsoft提出的應(yīng)用程序接口(API)用以實(shí)現(xiàn)訪問(wèn)關(guān)系或非關(guān)系數(shù)據(jù)庫(kù)中的數(shù)據(jù)。
ODBC(Open DataBase Connection)開(kāi)放式系統(tǒng)互連,是一種數(shù)據(jù)庫(kù)訪問(wèn)協(xié)議,提供了訪問(wèn)數(shù)據(jù)庫(kù)的API接口?;贠DBC的應(yīng)用程序,對(duì)數(shù)據(jù)庫(kù)操作不依賴(lài)于具體的DBMS,不直接與DBMS打交道,所有數(shù)據(jù)庫(kù)操作由對(duì)應(yīng)DBMS的ODBC驅(qū)動(dòng)程序完成,即:系統(tǒng)中不需要安裝DBMS系統(tǒng),如SQL SERVER 2005,但必須有SQL SERVER 2005的ODBC驅(qū)動(dòng)程序,然后在ODBC管理器中注冊(cè)數(shù)據(jù)源后,就可以在應(yīng)用程序中通過(guò)ODBC API訪問(wèn)該數(shù)據(jù)庫(kù)。ODBC數(shù)據(jù)庫(kù)訪問(wèn)技術(shù)只適用于windows系統(tǒng),因?yàn)樾枰贠DBC驅(qū)動(dòng)程序管理器中進(jìn)行數(shù)據(jù)源注冊(cè),而只有windows才集成了ODBC驅(qū)動(dòng)程序管理器(“控制面板/管理工具/數(shù)據(jù)源”)。
ADO具有跨系統(tǒng)平臺(tái)特性,它直接對(duì)DBMS數(shù)據(jù)庫(kù)進(jìn)行操作,即系統(tǒng)中必須有DBMS,但不需要驅(qū)動(dòng)程序,不需要注冊(cè)數(shù)據(jù)源,所以具有很好的可移植性。
那么,在Linux平臺(tái)如何連接和使用MSQL數(shù)據(jù)庫(kù)呢?我們同樣可以使用ADO、unixODBC或者M(jìn)ySQL API。這里不再贅述前兩者的用法,讀者可自行研究實(shí)踐,下文將詳細(xì)講解MySQL創(chuàng)建數(shù)據(jù)庫(kù)和C++利用MSQL API連接和操作數(shù)據(jù)庫(kù)。
2.MSQL數(shù)據(jù)庫(kù)的設(shè)計(jì)和建立
MySQL數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS)中,包含的MySQL中定義數(shù)據(jù)字段的類(lèi)型對(duì)你數(shù)據(jù)庫(kù)的優(yōu)化是非常重要的。MySQL支持多種類(lèi)型,大致可以分為三類(lèi):數(shù)值、日期/時(shí)間和字符串(字符)類(lèi)型。
本文以大學(xué)熟悉的學(xué)生選課管理系統(tǒng)中用到的數(shù)據(jù)庫(kù)為例,來(lái)實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的訪問(wèn)。本文數(shù)據(jù)庫(kù)的建立,是在Linux平臺(tái)使用msyql命令完成
主要有三張表:學(xué)生表,課程表和選課表。下面是數(shù)據(jù)表的詳細(xì)情況。
學(xué)生表:
課程表:
選課表:
3.MSQL數(shù)據(jù)庫(kù)的連接和操作
下面將講解利用MySQL API來(lái)編寫(xiě)我們自己的用于訪問(wèn)MySQL的中間件,也是我們自己的組件。我們的組件在應(yīng)用程序和MySQL數(shù)據(jù)庫(kù)之間構(gòu)成的層次結(jié)構(gòu)如下圖所示:
下面就來(lái)設(shè)計(jì)和實(shí)現(xiàn)我們自己的C++訪問(wèn)MySQL數(shù)據(jù)庫(kù)的組件。
3.1頭文件的設(shè)計(jì)
//mysqlhelper.h #ifndef __MYSQL_HELPER_H__ #define __MYSQL_HELPER_H__ #include#include
3.2源文件具體實(shí)現(xiàn)
//mysqlhelper.cpp #include "mysqlHelper.h" #include#include 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è)置字符集語(yǔ)句 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 >::const_iterator itEnd = mpColumns.end(); for(map >::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 >::const_iterator itEnd = mpColumns.end(); for(map >::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 >::const_iterator itEnd = mpColumns.end(); for(map >::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) { /** 沒(méi)有連上, 連接數(shù)據(jù)庫(kù) */ 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; /** 沒(méi)有連上, 連接數(shù)據(jù)庫(kù) */ 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 vtFields; MYSQL_FIELD *field; while((field = mysql_fetch_field(pstRes))) { vtFields.push_back(field->name); } map 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 &record):_record(record){} const string& MysqlHelper::MysqlRecord::operator[](const string &s) { map ::const_iterator it = _record.find(s); if(it == _record.end()) { throw MysqlHelper_Exception("field '" + s + "' not exists."); } return it->second; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// vector >& 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#include #include using namespace std; #include "mysqlHelper.h" using namespace mysqlhelper; int main(int argc,char* argv[]){ //初始化mysql對(duì)象并建立連接 MysqlHelper mysqlHelper; mysqlHelper.init("119.29.184.114","root","123456","StudentCourse"); try{ mysqlHelper.connect(); }catch(MysqlHelper_Exception& excep){ cout<
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}/*
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!