C++利用MySQL API连接和操作数据库实例详解

时间:2021-08-29 01:21:46

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

系列文章:

MySQL 设计和命令行模式下建立详解

在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命令完成

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

学生表:
C++利用MySQL API连接和操作数据库实例详解

课程表:
C++利用MySQL API连接和操作数据库实例详解

选课表:
C++利用MySQL API连接和操作数据库实例详解

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

下面将讲解利用MySQL API来编写我们自己的用于访问MySQL的中间件,也是我们自己的组件。我们的组件在应用程序和MySQL数据库之间构成的层次结构如下图所示:
C++利用MySQL API连接和操作数据库实例详解

下面就来设计和实现我们自己的C++访问MySQL数据库的组件。

3.1头文件的设计

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
//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源文件具体实现

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
//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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/****************************************************
*@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.4makefile

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
##################################
# @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}/*

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!