mysqltest01.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. #include <iostream>
  2. #include <mysql.h>
  3. #include <stdio.h>
  4. #include <mysql.h>
  5. #include <string>
  6. #include <time.h>
  7. #include <random>
  8. #include <thread>
  9. #include <chrono>
  10. #include <string.h>
  11. #include "CDBConnPool.h"
  12. #include "CDBHelper.h"
  13. void mysql_base_test()
  14. {
  15. MYSQL conn;
  16. int res = 0;
  17. mysql_init(&conn);
  18. if ( mysql_real_connect( &conn, "localhost", "root", "ok123", "yaxt", 0, NULL, CLIENT_FOUND_ROWS ) )
  19. {
  20. printf("connect success!\n");
  21. res = mysql_query( &conn, "insert into test01(id,name,type,BirthDate) values(3,'user',2,'2018-1-2 12:13:14')" );
  22. if ( res )
  23. {
  24. printf("error\n");
  25. }
  26. else
  27. {
  28. printf("OK\n");
  29. }
  30. mysql_close(&conn);
  31. }
  32. }
  33. void db_test_thread()
  34. {
  35. std::cout << "db_test_thread begin:[" << std::this_thread::get_id() << "]" << std::endl;
  36. //随机等待
  37. std::default_random_engine e;
  38. std::uniform_int_distribution<unsigned> u( 1, 9 );
  39. int r = u( e );
  40. std::this_thread::sleep_for( std::chrono::milliseconds( r * 100 ) );
  41. std::string Error;
  42. //从连接池中获得一个数据库连接
  43. YADB::CDBConnect *pConn = sDBConnPool.GetDBConnect( Error );
  44. if ( pConn )
  45. {
  46. //------------------------------------------------------
  47. //操作test01表,基础功能测试
  48. //------------------------------------------------------
  49. //插入
  50. char szInsert[1024] = { 0 };
  51. //线程ID的hash值实在是没法看,所以用很蠢的办法把线程ID赋给记录ID
  52. char szID[30] = { 0 };
  53. sprintf( szID, "%d", std::this_thread::get_id() );
  54. long long ID = atoll( szID );
  55. std::string Name = "Tom.J";
  56. int Type = 1;
  57. std::string BirthDate = "2017-12-1 09:13:45";
  58. my_ulonglong ullRes = 0;
  59. //插入记录
  60. sprintf( szInsert, "insert into test01(ID,Name,Type,BirthDate) values (%lld, \'%s\', %d,\'%s\')", ID, Name.c_str(), Type, BirthDate.c_str() );
  61. ullRes = pConn->ExecuteRealSql( szInsert, Error );
  62. if ( YADB::DB_ERR_EXCUTE_QUERY == ullRes )
  63. {
  64. printf( "插入记录失败:%s!\n", Error.c_str() );
  65. Error = pConn->GetLastError();
  66. }
  67. else
  68. {
  69. printf( "插入记录成功!\n" );
  70. }
  71. //查询
  72. YADB::CDBResultSet *pRes = pConn->ExecuteQuery( "select * from test01", Error );
  73. my_ulonglong ResCount = pRes->GetRecordCount( Error );
  74. printf( "Record count = %lld\n", ResCount );
  75. while ( pRes->GetNextRecod( Error ) )
  76. {
  77. long long ID = 0;
  78. pRes->GetField( "ID", ID, Error );
  79. std::string strName;
  80. pRes->GetField( "Name", strName, Error );
  81. char szName[100] = { 0 };
  82. pRes->GetField( "Name", szName, sizeof( szName ), Error );
  83. int Type = 0;
  84. pRes->GetField( "Type", Type, Error );
  85. std::string Birth;
  86. pRes->GetField( "BirthDate", Birth, Error );
  87. MYSQL_TIME dtBirth;
  88. pRes->GetField( "BirthDate", dtBirth, Error );
  89. printf( "ID=%lld Name=%s Type=%d BirthDate=%s\n", ID, strName.c_str(), Type, Birth.c_str() );
  90. }
  91. //修改
  92. memset( szInsert , 0, sizeof( szInsert ) );
  93. Name = "李明";
  94. BirthDate = "2018-1-1 01:01:01";
  95. sprintf( szInsert, "update test01 set Name='%s\',BirthDate ='%s\' where ID=%lld", Name.c_str(), BirthDate.c_str(), ID );
  96. ullRes = pConn->ExecuteRealSql( szInsert, Error );
  97. if ( YADB::DB_ERR_EXCUTE_QUERY == ullRes )
  98. {
  99. printf( "更新记录失败:%s!\n", Error.c_str() );
  100. }
  101. else
  102. {
  103. printf( "更新记录成功!\n" );
  104. }
  105. //删除
  106. memset( szInsert, 0, sizeof( szInsert ) );
  107. sprintf( szInsert, "delete from test01 where ID=%lld", ID );
  108. ullRes = pConn->ExecuteSql( szInsert, Error );
  109. if ( YADB::DB_ERR_EXCUTE_QUERY == ullRes )
  110. {
  111. printf( "删除记录失败:%s!\n", Error.c_str() );
  112. }
  113. else
  114. {
  115. printf( "删除记录成功!\n" );
  116. }
  117. //用预处理方式出入记录
  118. long long LID = 100000000 + ID;
  119. char name[20] = "Jarry";
  120. long nameLen = strlen( name );
  121. int type = 2;
  122. MYSQL_TIME ts;
  123. ts.year = 2018;
  124. ts.month = 1;
  125. ts.day = 13;
  126. ts.hour = 13;
  127. ts.minute = 15;
  128. ts.second = 16;
  129. ts.second_part = 0;
  130. ts.time_type = MYSQL_TIMESTAMP_DATE;
  131. MYSQL_BIND bindData[4];
  132. memset( bindData, 0, sizeof( bindData ) );
  133. bindData[0].buffer_type = MYSQL_TYPE_LONGLONG;
  134. bindData[0].buffer = ( long long * ) &LID;
  135. bindData[0].is_null = 0;
  136. bindData[1].buffer_type = MYSQL_TYPE_STRING;
  137. bindData[1].buffer = ( char * ) name;
  138. bindData[1].buffer_length = nameLen;
  139. bindData[1].is_null = 0;
  140. bindData[1].length = ( unsigned long* ) &nameLen;
  141. bindData[2].buffer_type = MYSQL_TYPE_LONG;
  142. bindData[2].buffer = &type;
  143. bindData[2].is_null = 0;
  144. bindData[3].buffer_type = MYSQL_TYPE_DATETIME;
  145. bindData[3].buffer = ( char * ) &ts;
  146. bindData[3].is_null = 0;
  147. bindData[3].length = 0;
  148. if ( !pConn->stmtExcute( bindData, 0, Error ) )
  149. {
  150. printf( "执行预处理失败:%s!\n", Error.c_str() );
  151. }
  152. else
  153. {
  154. printf( "执行预处理成功!\n" );
  155. //删除
  156. memset( szInsert, 0, sizeof( szInsert ) );
  157. sprintf( szInsert, "delete from test01 where ID=%lld", LID );
  158. ullRes = pConn->ExecuteSql( szInsert, Error );
  159. if ( YADB::DB_ERR_EXCUTE_QUERY == ullRes )
  160. {
  161. printf( "删除记录失败:%s!\n", Error.c_str() );
  162. }
  163. else
  164. {
  165. printf( "删除记录成功!\n" );
  166. }
  167. }
  168. //------------------------------------------------------
  169. //操作test02表,test02表的ID字段是自增的
  170. //------------------------------------------------------
  171. //插入记录
  172. sprintf( szInsert, "insert into test02(Name,Type,BirthDate) values (\'%s\', %d,\'%s\')", Name.c_str(), Type, BirthDate.c_str() );
  173. ullRes = pConn->ExecuteRealSql( szInsert, Error );
  174. if ( YADB::DB_ERR_EXCUTE_QUERY == ullRes )
  175. {
  176. printf( "插入记录失败:%s!\n", Error.c_str() );
  177. Error = pConn->GetLastError();
  178. }
  179. else
  180. {
  181. printf( "插入记录成功!\n" );
  182. }
  183. my_ulonglong InsertedID = pConn->GetLastInsertID( Error );
  184. printf( "新插入ID:%lld!\n", InsertedID );
  185. //删除
  186. memset( szInsert, 0, sizeof( szInsert ) );
  187. sprintf( szInsert, "delete from test02 where ID=%lld", InsertedID );
  188. ullRes = pConn->ExecuteSql( szInsert, Error );
  189. if ( YADB::DB_ERR_EXCUTE_QUERY == ullRes )
  190. {
  191. printf( "删除记录失败:%s!\n", Error.c_str() );
  192. }
  193. else
  194. {
  195. printf( "删除记录成功!\n" );
  196. }
  197. //------------------------------------------------------
  198. //操作test01表,事务测试
  199. //------------------------------------------------------
  200. pConn->AutoCommit( false, Error );//把自动提交设置成false
  201. Name = "GuaGua";
  202. LID = 900000000 + ID;
  203. sprintf( szInsert, "insert into test01(ID,Name,Type,BirthDate) values (%lld, \'%s\', %d,\'%s\')", LID, Name.c_str(), Type, BirthDate.c_str() );
  204. ullRes = pConn->ExecuteRealSql( szInsert, Error );
  205. if ( YADB::DB_ERR_EXCUTE_QUERY == ullRes )
  206. {
  207. printf( "插入记录失败:%s!\n", Error.c_str() );
  208. Error = pConn->GetLastError();
  209. }
  210. else
  211. {
  212. printf( "插入记录成功!\n" );
  213. }
  214. //pConn->Commit( Error );//提交
  215. pConn->RollBack( Error );//回滚
  216. pConn->AutoCommit( true, Error );//把自动提交设置成true
  217. //归还数据库连接
  218. sDBConnPool.GiveBack( pConn );
  219. //异步执行测试
  220. printf( "异步执行测试开始!\n" );
  221. char szSQL[1024] = { 0 };
  222. //memset( szSQL, 0, sizeof( szSQL ) );
  223. sprintf( szSQL, "insert into test01(ID,Name,Type,BirthDate) values (%lld, \'%s\', %d,\'%s\')", LID, "Mike", 3, "2000-1-1 12:13:14" );
  224. sDBConnPool.PushAsync( szSQL );
  225. memset( szSQL, 0, sizeof( szSQL ) );
  226. sprintf( szSQL, "delete from test01 where ID=%lld", LID );
  227. sDBConnPool.PushAsync( szSQL );
  228. printf( "异步执行测试结束!\n" );
  229. }
  230. //显示线程信息
  231. std::cout << "[" << std::this_thread::get_id() << "]" << " db_test_thread end!\n" ;
  232. }
  233. //在多线程环境下测试
  234. void thread_db_class_test()
  235. {
  236. printf( "----------------------------------------------------------------\n" );
  237. printf( " 多线程测试 \n" );
  238. printf( "----------------------------------------------------------------\n" );
  239. YADB::_DB_POOL_SETTING_ DBSetting;
  240. DBSetting.Host = "localhost";
  241. DBSetting.User = "root";
  242. DBSetting.PWD = "ok123";
  243. DBSetting.DBName = "yaxt";
  244. //DBSetting.CharSet = "GB2312";
  245. DBSetting.CharSet = "utf8";
  246. DBSetting.TimeOut = 5;
  247. DBSetting.PoolSize = 10;
  248. DBSetting.stmtSQL = "insert into test01(ID,Name,Type,BirthDate) values (?,?,?,?)";
  249. std::string Error;
  250. //创建连接池
  251. if ( !sDBConnPool.Create( DBSetting, Error ) )
  252. {
  253. printf( "线程池创建失败,Err=%s\n", Error.c_str() );
  254. return;
  255. }
  256. //多线程测试
  257. int ThreadCount = 1;//线程数
  258. for ( int i = 0; i < ThreadCount; i++ )
  259. {
  260. std::thread t( db_test_thread );
  261. t.detach();
  262. }
  263. sDBConnPool.Close();
  264. }
  265. void simple_db_class_test()
  266. {
  267. printf("----------------------------------------------------------------\n");
  268. printf(" 简单测试 \n");
  269. printf("----------------------------------------------------------------\n");
  270. YADB::_DB_POOL_SETTING_ DBSetting;
  271. DBSetting.Host = "localhost";
  272. DBSetting.User = "root";
  273. DBSetting.PWD = "ok123";
  274. DBSetting.DBName = "yaxt";
  275. DBSetting.CharSet = "utf8";
  276. DBSetting.TimeOut = 5;
  277. DBSetting.PoolSize = 10;
  278. DBSetting.stmtSQL = "insert into test01(ID,Name,Type,BirthDate) values (?,?,?,?)";
  279. std::string Error;
  280. //创建连接池
  281. if ( !sDBConnPool.Create( DBSetting, Error ) )
  282. {
  283. printf("线程池创建失败,Err=%s\n", Error.c_str());
  284. return;
  285. }
  286. YADB::CDBHelper DBHelper;
  287. YADB::CDBResultSet DBRes;
  288. sDBConnPool.Query( "select * from test01", DBRes, Error );
  289. int nCount = DBRes.GetRecordCount( Error );
  290. if (nCount > 0)
  291. {
  292. printf( "The record count=%d\n", nCount );
  293. while ( DBRes.GetNextRecod(Error) )
  294. {
  295. long long ID = 0;
  296. DBRes.GetField( "ID", ID, Error );
  297. char szName[100] = { 0 };
  298. DBRes.GetField( "Name", szName, sizeof( szName ), Error );
  299. std::string strName;
  300. DBRes.GetField( "Name", strName, Error );
  301. int Type = 0;
  302. DBRes.GetField( "Type", Type, Error );
  303. unsigned int uType = 0;
  304. DBRes.GetField( "Type", uType, Error );
  305. std::string Birth;
  306. DBRes.GetField( "BirthDate", Birth, Error );
  307. float fValue = 0.0;
  308. DBRes.GetField( "FloatField", fValue, Error );
  309. double dValue = 0.0;
  310. DBRes.GetField( "DoubleField", dValue, Error );
  311. bool bValue = false;
  312. DBRes.GetField( "BoolField", bValue, Error );
  313. MYSQL_TIME dtBirth;
  314. DBRes.GetField( "DateTimeField", dtBirth, Error );
  315. char szBirth[40] = { 0 };
  316. DBHelper.DateTime2String( dtBirth, szBirth, sizeof( szBirth ) );
  317. std::cout << "ID=" << ID << " ";
  318. std::cout << "Name=" << szName << " ";
  319. std::cout << "Name=" << strName.c_str() << " ";
  320. std::cout << "Type=" << Type << " ";
  321. std::cout << "Type=" << uType << " ";
  322. std::cout << "BirthDate=" << Birth << " ";
  323. std::cout << "FloatField=" << fValue << " ";
  324. std::cout << "DoubleField=" << dValue << " ";
  325. std::cout << "BoolField=" << bValue << " ";
  326. std::cout << "DateTimeField=" << szBirth << " ";
  327. std::cout << std::endl;
  328. }
  329. }
  330. std::string strUptSQL;
  331. strUptSQL = "update test01 set DoubleField=1.888888 where ID=1";
  332. if ( sDBConnPool.ExecuteSql( strUptSQL.c_str(), Error ) < 0 )
  333. {
  334. printf( "Err,Failed to ExecuteSql:%s,Err=%s\n", strUptSQL.c_str(), Error.c_str() );
  335. }
  336. }
  337. void stmt_test()
  338. {
  339. printf("----------------------------------------------------------------\n");
  340. printf(" 预处理测试 \n");
  341. printf("----------------------------------------------------------------\n");
  342. YADB::_DB_POOL_SETTING_ DBSetting;
  343. DBSetting.Host = "localhost";
  344. DBSetting.User = "root";
  345. DBSetting.PWD = "ok123";
  346. DBSetting.DBName = "yaxt";
  347. DBSetting.CharSet = "utf8";
  348. DBSetting.TimeOut = 5;
  349. DBSetting.PoolSize = 10;
  350. std::string Error;
  351. //创建连接池
  352. if ( !sDBConnPool.Create( DBSetting, Error ) )
  353. {
  354. printf( "线程池创建失败,Err=%s\n", Error.c_str() );
  355. return;
  356. }
  357. YADB::CDBConnect *pConn = sDBConnPool.GetDBConnect( Error );
  358. //delete old record
  359. pConn->ExecuteSql( "delete from test01 where ID >=10000", Error );
  360. //insert new record bystmt
  361. if ( !pConn->Preparestmt( "insert into test01(ID,Name,Type,BirthDate) values (?,?,?,?)", Error ) )
  362. {
  363. printf("Invoke Preparestmt失败,Err=%s\n", Error.c_str());
  364. return;
  365. }
  366. for ( int i = 10000; i <= 10010000; i++ )
  367. {
  368. long long LID = i;
  369. char name[20] = "Jarry";
  370. long nameLen = strlen(name);
  371. int type = 2;
  372. MYSQL_TIME ts;
  373. ts.year = 2018;
  374. ts.month = 1;
  375. ts.day = 13;
  376. ts.hour = 13;
  377. ts.minute = 15;
  378. ts.second = 16;
  379. ts.second_part = 0;
  380. ts.time_type = MYSQL_TIMESTAMP_DATE;
  381. MYSQL_BIND bindData[4];
  382. memset(bindData, 0, sizeof(bindData));
  383. bindData[0].buffer_type = MYSQL_TYPE_LONGLONG;
  384. bindData[0].buffer = (long long *) &LID;
  385. bindData[0].is_null = 0;
  386. bindData[1].buffer_type = MYSQL_TYPE_STRING;
  387. bindData[1].buffer = (char *) name;
  388. bindData[1].buffer_length = nameLen;
  389. bindData[1].is_null = 0;
  390. bindData[1].length = (unsigned long*) &nameLen;
  391. bindData[2].buffer_type = MYSQL_TYPE_LONG;
  392. bindData[2].buffer = &type;
  393. bindData[2].is_null = 0;
  394. bindData[3].buffer_type = MYSQL_TYPE_DATETIME;
  395. bindData[3].buffer = (char *) &ts;
  396. bindData[3].is_null = 0;
  397. bindData[3].length = 0;
  398. if ( !pConn->stmtExcute( bindData, 0, Error ) )
  399. {
  400. printf("执行预处理失败:%s!\n", Error.c_str());
  401. }
  402. }
  403. printf("预处理完成!\n");
  404. }
  405. int main()
  406. {
  407. //mysql_base_test();
  408. simple_db_class_test();
  409. //thread_db_class_test();
  410. //stmt_test();
  411. printf( "Press Enter key to continue...\n" );
  412. fgetc( stdin );
  413. printf( "All Done!\n" );
  414. return 0;
  415. }