1.C++连接和操作MySQL的方式
系列文章:
MySQL 设计和命令行模式下建立详解
C++利用MySQL API连接和操作数据库实例详解
在Windows平台,我们可以使用ADO、ODBC或者MySQL API进行连接和操作。ADO (ActiveX Data Objects,ActiveX数据对象)是Microsoft提出的一个用于存取数据源的COM组件。它提供了程序语言和统一数据访问方式OLE DB的一个中间层,也就是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数据库进行操作,即系统中必须有DBMS,但不需要驱动程序,不需要注册数据源,所以具有很好的可移植性。
那么,在Linux平台如何连接和使用MSQL数据库呢?我们同样可以使用ADO、unixODBC或者MySQL API。这里不再赘述前两者的用法,读者可自行研究实践,下文将详细讲解MySQL创建数据库和C++利用MSQL API连接和操作数据库。
2.MSQL数据库的设计和建立
MySQL数据库管理系统(DBMS)中,包含的MySQL中定义数据字段的类型对你数据库的优化是非常重要的。MySQL支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。
本文以大学熟悉的学生选课管理系统中用到的数据库为例,来实现对数据库的访问。本文数据库的建立,是在Linux平台使用msyql命令完成
主要有三张表:学生表,课程表和选课表。下面是数据表的详细情况。
3.MSQL数据库的连接和操作
下面就来设计和实现我们自己的C++访问MySQL数据库的组件。
3.1头文件的设计
//mysqlhelper.h
#ifndef __MYSQL_HELPER_H__
#define __MYSQL_HELPER_H__
#include
#include
3.2源文件具体实现
//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);
}
//建立连接后, 自动调用设置字符集语句
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)
{
/**
没有连上, 连接数据库
*/
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 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对象并建立连接
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}/*
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
暂时没有评论,来抢沙发吧~