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.MSQL数据库的设计和建立

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

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

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

学生表:

课程表:

选课表:

3.MSQL数据库的连接和操作

下面将讲解利用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;//删除一条学生记录,学号为201421031059try{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.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/libCPPDIRS=.
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}/*

C++利用MySQL API连接和操作数据库相关推荐

  1. vc mysql控件_VC++使用ActiveX控件连接和操作数据库

    VS2008运用ActiveX控件连接和操作数据库关闭时一直有个内存释放的错误,好像使用VC6.0会多生成2个文件,就不会有问题. VC++使用ActiveX控件连接和操作数据库的方法分两种: 1.通 ...

  2. 使用Spring JDBC框架连接并操作数据库

    在前一篇博文JAVA通过JDBC连接并操作MySQL数据库中,我们知道如何通过JDBC连接并操作数据库,但是请看程序,整个程序连接数据库和关闭数据库占了很大一部分代码量,而且每次我们执行一下数据库操作 ...

  3. php django mysql配置文件_Mysql学习Django+mysql配置与简单操作数据库实例代码

    <Mysql学习Django+mysql配置与简单操作数据库实例代码>要点: 本文介绍了Mysql学习Django+mysql配置与简单操作数据库实例代码,希望对您有用.如果有疑问,可以联 ...

  4. 数据库应用——MySQL基础知识和操作数据库

    这里写目录标题 初识MySQL 什么是数据库 数据库分类 MySQL简介 安装MYSQL win10安装 安装SQLyog 连接数据库 linux安装 使用Navicat Premium连接数据库 操 ...

  5. 如何利用MySQL的binlog恢复误删数据库详解

    文章来源: 学习通http://www.bdgxy.com/ 目录 1 查看当前数据库内容并备份数据库 2 开启bin_log功能 3 模拟误操作(插入3条数据,删除数据库) 4 数据恢复 5 总结 ...

  6. 使用python简单连接并操作数据库

    python中连接并操作数据库 图示操作流程 一.使用的完整流程 # 1. 导入模块 from pymysql import connect# 2. 创建和数据库服务器的连接,自行设置 服务器地址,端 ...

  7. mysql怎么连接别人的数据库

    mysql怎么连接别人的数据库呢?(Navicat for MySQL版) 其实很简单 首先主机要添加几个用户使用 需要打开mysql这个数据库 然后新建查询->输入以下代码 GRANT ALL ...

  8. C++连接mysql的两种方式(ADO连接和mysql api连接)

    一.ADO连接mysql 1.安装mysql-5.5.20-win32.msi和mysql-connector-odbc-5.3.4-win32.msi(一般两个安装程序要匹配,否则可能连接不上)   ...

  9. Java 技术篇-java连接并操作数据库实例演示,执行查询、插入、更新和删除操作

    Java 操作数据库 第一章:Java 代码四个类实现 ① 项目结构展示 ② 数据库连接类 ③ 数据库查询类 ④ 数据库更新类 ⑤ 数据库主类 第二章:查询和更新操作实例演示 ① 查询操作演示 ② 更 ...

最新文章

  1. Centos 的inotify和rsync文件实时同步
  2. Asp.NET Core 如何使用ElasticSearch和Kibana创建仪表板
  3. 图解算法学习笔记(七):狄克斯特拉算法
  4. 腾讯手机管家筹划“出海”
  5. js处理16进制hex转str出现的中文乱码问题
  6. 科技前沿及论文写作相关视频
  7. yii 下 session 丢失的问题
  8. java架构《并发线程中级篇》
  9. ceisum加载shp格式的城市白模建筑数据
  10. 由于未安装.net framework 4.0的miscrosoft office支持,无法加载以下解决方案 ***.vsto
  11. 小心 transmittable-thread-local 的这个坑
  12. 视频教程-Kali Linux渗透测试全程课与脚本语言编程系列课程-渗透测试
  13. S5PV210 对电源、地,DQ, DQM, DQS 信号的布线向导
  14. 稀疏矩阵(三元组顺序表存储)6种操作的实现
  15. Docker实现原理之 - OverlayFS实现原理
  16. 计算机网络校园局域网课题,毕业论文基于VLAN技术的校园局域网建设word文档_全文免费在线阅读(推荐阅读)...
  17. Python 字符串格式化 f-string f“{}“ .format
  18. Android平台接入Facebook登录
  19. Python+Vue计算机毕业设计超市积分管理系统o2qyn(源码+程序+LW+部署)
  20. 字节跳动秋招提前批客户端面试(已oc)

热门文章

  1. 每 1000 行代码有 14 个安全缺陷,开源软件的安全令人堪忧
  2. 在Zuul中设置服务访问限流
  3. 动态传参, 名称空间, 嵌套, gloabal, nonlocal
  4. vue移动端项目中统一滚动条样式与效果
  5. windows7下bcdedit出现“拒绝访问”解决办法
  6. SEO 搜索引擎优化技巧
  7. python压缩与读取.tar.bz2压缩包
  8. Spring源码学习笔记:经典设计模式之策略模式
  9. PAT 1084. 外观数列 (20) - 乙级
  10. 判断用户 小程序_解读微信小程序用户运营四部曲