0


C++连接mysql(改进)

使用vs2019对window11中的数据库进行连接

1. 配置连接环境

首先需要把mysql中的头文件和库文件放入到c++项目工程中

1.打开安装MySQL的目录,在windows系统中如果是默认路径,应该和我的是一样的:C:\Program Files\MySQL\MySQL Server 8.0

2.找到include,和lib文件,include文件是包含的头文件,lib文件是包含的库文件

3.在创建的c++工程中加入include,lib文件路径,按一下步骤

1.工程中的项目找到属性

2.到 VC++ 目录 中的包含目录和库目录分别加入include文件和lib文件的路径,

这是我的路径:include文件路径:C:\Program Files\MySQL\MySQL Server 8.0\include

lib文件路径:C:\Program Files\MySQL\MySQL Server 8.0\lib

  1. 到 链接器 中的 输入 中的 附加依赖项中 加入 libmysql.lib 的依赖:

4.还需要把下图中的 libmysql.dll 的文件复制到 C:\Windows\System32 目录中

连接mysql可以参考 mysql参考手册 进行查看

2.代码实现连接

例子:

  1. #define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<mysql.h>#include<time.h>#include<stdlib.h>intmain(){
  2. int sr;
  3. srand((unsigned)time(NULL));
  4. sr = rand() % 50 + 1;
  5. //固定不变的
  6. MYSQL mysql; //一个数据库结构体
  7. MYSQL_RES* res; //一个结果集结构体
  8. MYSQL_ROW row; //char** 二维数据,存放一条条记录
  9. //初始化数据库
  10. mysql_init(&mysql);
  11. //设置编码方式
  12. mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk");
  13. //连接数据库 //ip地址 //用户名 //密码 //数据库名
  14. if (mysql_real_connect(&mysql, "localhost", "root", "Z20020803", "box_man", 3306, NULL, 0) == NULL)
  15. {
  16. printf("错误原因:%s\n", mysql_error(&mysql));
  17. printf("连接失败\n");
  18. exit(-1);
  19. }
  20. //往数据库中插入一个随机数
  21. char* str1 = "insert into rand values(";
  22. char sql_insert[200];
  23. sprintf(sql_insert, "%s%d%s", str1, sr, ")");
  24. mysql_query(&mysql, sql_insert); //sql语句提交
  25. //查询数据
  26. mysql_query(&mysql, "select * from rand");
  27. //获取结果集
  28. res = mysql_store_result(&mysql);
  29. //给ROW赋值,判断ROW是否为空,不为空就打印数据
  30. while (row = mysql_fetch_row(res))
  31. {
  32. printf("%s\n", row[0]);
  33. }
  34. //释放结果集
  35. mysql_free_result(res);
  36. //关闭数据库
  37. mysql_close(&mysql);
  38. //停留等待
  39. system("pause");
  40. return0;
  41. }

使用c++语句对数据库进行增删改查,在使用c++中string类型时,需要把string类型转换为c中的类型,使用mysql_query函数把sql语句提交,查询成功返回0,结果会被保存到mysql对象中,查询失败会返回非0值:

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include<iostream>
  3. #include<mysql.h>
  4. #include<string>
  5. usingnamespace std;
  6. intmain(){
  7. MYSQL mysql;
  8. MYSQL_RES* res;
  9. MYSQL_ROW row;
  10. mysql_init(&mysql);
  11. if (mysql_real_connect(&mysql, "localhost", "root", "Z20020803", "box_man", 3306, NULL, 0) == NULL)
  12. {
  13. printf("错误提示:%s\n", mysql_error(&mysql));
  14. printf("连接失败\n");
  15. }
  16. //设置字符集
  17. mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk");
  18. string str1 = "alter table tb_77 modify sex varchar(20)";//修改表类型失败
  19. mysql_query(&mysql, str1.c_str());
  20. string str = "insert into tb_77 values(5,'sdmqy','h')";//增加数据成功,不可以增加汉字
  21. mysql_query(&mysql, str.c_str());
  22. printf("%s", str.c_str());
  23. string str2 = "delete from tb_77 where sex = '女';";//删除数据成功
  24. mysql_query(&mysql, str2.c_str());
  25. string str3 = "update tb_77 set name = 'ttb' where id = 2";//更改也行
  26. mysql_query(&mysql, str3.c_str());
  27. mysql_close(&mysql);
  28. return0;
  29. }

3.各个类说明:

  1. mysql句柄类(是一个结构体)

1

MYSQL mysql;

该类在c++中操作数据库都要使用到

结构体原型:

  1. typedef struct MYSQL {
  2. NET net; /* Communication parameters */
  3. unsigned char *connector_fd; /* ConnectorFd for SSL */
  4. char *host, *user, *passwd, *unix_socket, *server_version, *host_info;
  5. char *info, *db;
  6. struct CHARSET_INFO *charset;
  7. MYSQL_FIELD *fields;
  8. struct MEM_ROOT *field_alloc;
  9. uint64_t affected_rows;
  10. uint64_t insert_id; /* id if insert on table with NEXTNR */
  11. uint64_t extra_info; /* Not used */
  12. unsigned long thread_id; /* Id for connection in server */
  13. unsigned long packet_length;
  14. unsigned int port;
  15. unsigned long client_flag, server_capabilities;
  16. unsigned int protocol_version;
  17. unsigned int field_count;
  18. unsigned int server_status;
  19. unsigned int server_language;
  20. unsigned int warning_count;
  21. struct st_mysql_options options;
  22. enum mysql_status status;
  23. enum enum_resultset_metadata resultset_metadata;
  24. bool free_me; /* If free in mysql_close */
  25. bool reconnect; /* set to 1 if automatic reconnect */
  26. /* session-wide random string */
  27. char scramble[SCRAMBLE_LENGTH + 1];
  28. LIST *stmts; /* list of all statements */
  29. const struct MYSQL_METHODS *methods;
  30. void *thd;
  31. /*
  32. Points to boolean flag in MYSQL_RES or MYSQL_STMT. We set this flag
  33. from mysql_stmt_close if close had to cancel result set of this object.
  34. */
  35. bool *unbuffered_fetch_owner;
  36. void *extension;
  37. } MYSQL;

2.MYSQL_RES查询结果集(是一个结构体)

2

MYSQL_RES * res=nullptr;

用来保存查询到的所有结果

结构体原型:

  1. typedef struct MYSQL_RES {
  2. uint64_t row_count;
  3. MYSQL_FIELD *fields;
  4. struct MYSQL_DATA *data;
  5. MYSQL_ROWS *data_cursor;
  6. unsigned long *lengths; /* column lengths of current row */
  7. MYSQL *handle; /* for unbuffered reads */
  8. const struct MYSQL_METHODS *methods;
  9. MYSQL_ROW row; /* If unbuffered read */
  10. MYSQL_ROW current_row; /* buffer to current row */
  11. struct MEM_ROOT *field_alloc;
  12. unsigned int field_count, current_field;
  13. bool eof; /* Used by mysql_fetch_row */
  14. /* mysql_stmt_close() had to cancel this result */
  15. bool unbuffered_fetch_cancelled;
  16. enum enum_resultset_metadata metadata;
  17. void *extension;
  18. } MYSQL_RES;

3.MYSQL_ROW获取结果集中的内容:本质上是一个char类型的二级指针

MYSQL_ROW row

该变量可以获取到结果集中的数据

4.MYSQL_FIELD获取结果集中表的所有内容(是一个结构体)

结构体原型:

  1. typedef struct MYSQL_FIELD {
  2. char *name; /* Name of column */
  3. char *org_name; /* Original column name, if an alias */
  4. char *table; /* Table of column if column was a field */
  5. char *org_table; /* Org table name, if table was an alias */
  6. char *db; /* Database for table */
  7. char *catalog; /* Catalog for table */
  8. char *def; /* Default value (set by mysql_list_fields) */
  9. unsigned long length; /* Width of column (create length) */
  10. unsigned long max_length; /* Max width for selected set */
  11. unsigned int name_length;
  12. unsigned int org_name_length;
  13. unsigned int table_length;
  14. unsigned int org_table_length;
  15. unsigned int db_length;
  16. unsigned int catalog_length;
  17. unsigned int def_length;
  18. unsigned int flags; /* Div flags */
  19. unsigned int decimals; /* Number of decimals in field */
  20. unsigned int charsetnr; /* Character set */
  21. enum enum_field_types type; /* Type of field. See mysql_com.h for types */
  22. void *extension;
  23. } MYSQL_FIELD;

4.一些函数说明

mysql的使用手册网址:MySQL :: MySQL 8.0 C API 开发人员指南 :: 5.4.23 mysql_field_count()

部分API函数

函数

作用

mysql_init()

获取或初始化MYSQL结构。

mysql_real_connect()

连接到MySQL服务器。

mysql_query()

执行指定为“以Null终结的字符串”的SQL查询。

mysql_store_result()

检索完整的结果集至客户端。

mysql_use_result()

初始化逐行的结果集检索

mysql_fetch_field()

返回下一个表字段的类型。

mysql_fetch_fields()

返回所有字段结构的数组。

mysql_fetch_lengths()

返回当前行中所有列的长度。

mysql_fetch_row()

从结果集中获取下一行

mysql_field_count()

返回上次执行语句的结果列的数目。

mysql_free_result()

释放结果集使用的内存。

mysql_close()

关闭服务器连接。

mysql_autocommit()

切换 autocommit模式,ON/OFF

mysql_commit()

提交事务。

mysql_errno()

返回上次调用的MySQL函数的错误编号

mysql_options()

为mysql_connect()设置连接选项

mysql_ping()

检查与服务器的连接是否工作,如有必要重新连接。

在下列函数中,从连接数据库到获取数据库中的数据主要使用到1-7的函数。

1.mysql_init函数:初始化MYSQL变量

函数原型:

  1. MYSQL *mysql_init(MYSQL *mysql)
  2. 说明:
  3. 1.如果mysqlNULL指针,该函数将分配、初始化、并返回新对象。
  4. 2.否则,将初始化对象,并返回对象的地址。
  5. 3.如果mysql_init()分配了新的对象,应当在程序中调用mysql_close() 来关闭连接,以释放对象
  6. 参数解释:
  7. 返回值:初始化的MYSQL*句柄。如果无足够内存以分配新的对象,返回NULL
  8. 错误,在内存不足的情况下,返回NULL
2.mysql_read_connect函数:使用该函数连接mysql数据库

函数原型:

  1. mysql_real_connect
  2. MYSQL *mysql ///< 数据库句柄
  3. constchar *host ///< 主机名
  4. constchar *user ///< 用户名
  5. constchar *passwd///< 密码
  6. constchar *db ///< 数据库名
  7. unsignedint port ///< 端口号(MySQL为3306)
  8. constchar *unix_socket///< unix_socket–unix连接方式,为NULL时表示不使用socket或管道机制
  9. unsignedlong clientflag ///< clientflag–Mysql运行为ODBC数据库的标记,一般取0,该参数可以设置提交的sql语句为多条语句
  10. );
  11. 作用:连接数据库引擎,通过函数mysql_real_connect()尝试与运行在主机上的MySQL数据库引擎建立连接。
  12. 返回值:如果连接成功,返回MYSQL*连接句柄。如果连接失败,返回NULL。对于成功的连接,返回值与第1个参数的值相同。
3.mysql_real_query和mysql_query函数:进行数据库查询(也就是递交sql语句)

函数原型:

  1. int STDCALL mysql_real_query(MYSQL *mysql, const char *query, unsigned long length);
  2. 说明:执行由“Null终结的字符串”查询指向的SQL查询。
  3. 正常情况下,字符串必须包含1SQL语句,而且不应为语句添加终结分号(‘;’)或“\g”。
  4. 如果允许多语句执行,字符串可包含多条由分号隔开的语句。(“多查询执行的C API处理”)mysql_query()
  5. 不能用于包含二进制数据的查询,应使用mysql_real_query()取而代之(二进制数据可能包含字符‘\0’,
  6. mysql_query()会将该字符解释为查询字符串结束)。如果希望了解查询是否应返回结果集,
  7. 可使用mysql_field_count()进行检查。
  8. 返回值:如果查询成功,返回0。如果出现错误,返回非0值。
  9. int mysql_query(MYSQL *mysql, const char *query)
  10. 返回值:如果查询成功,返回0。如果出现错误,返回非0值。
  11. 参数解释:
  12. 参数mysql:前面使用MYSQL结构体定义的变量;
  13. 参数querysql语句
  14. 参数lengthsql语句的长度
4.mysql_store_result和mysql_use_result函数:获取查询结果数据

函数原型:

  1. MYSQL_RES *mysql_store_result(MYSQL *mysql)
  2. 说明:
  3. 1.对于成功检索了数据的每个查询(SELECTSHOWDESCRIBEEXPLAINCHECK TABLE等)
  4. ,必须调用mysql_store_result()或mysql_use_result()
  5. 2.如果希望了解查询是否应返回结果集,可使用mysql_field_count()进行检查。
  6. 3.如果查询未返回结果集,mysql_store_result()将返回Null指针(例如,
  7. 如果查询是INSERT语句)。
  8. 4.如果读取结果集失败,mysql_store_result()还会返回Null指针。通过检查mysql_error()
  9. 是否返回非空字符串,mysql_errno()是否返回非0值,或mysql_field_count()是否返回0
  10. 可以检查是否出现了错误。
  11. 5.如果未返回行,将返回空的结果集。(空结果集设置不同于作为返回值的空指针)。
  12. 6.一旦调用了mysql_store_result()并获得了不是Null指针的结果,可调用
  13. mysql_num_rows()来找出结果集中的行数。
  14. 7.可以调用mysql_fetch_row()来获取结果集中的行,或调用mysql_row_seek()和
  15. mysql_row_tell()来获取或设置结果集中的当前行位置。
  16. 8.一旦完成了对结果集的操作,必须调用mysql_free_result()。
  17. 返回值:具有多个结果的MYSQL_RES结果集合。如果出现错误,返回NULL
  18. MYSQL_RES * mysql_use_result(MYSQL *mysql);
  19. 说明:调用mysql_use_result初始化检索,以便于后面一行一行的读取结果集,而它本身并没有从
  20. 服务器读取任何数据,这种方式较之第一种速度更快且所需内存更少,但它会绑定服务器,阻止其他线程
  21. 更新任何表,而且必须重复执行mysql_fetch_row读取数据,直至返回NULL,否则未读取的行会在下一
  22. 次查询时作为结果的一部分返回,故经常我们使用mysql_store_result
5.mysql_fetch_row函数:读取结果集数据

函数原型:

  1. MYSQL_ROW mysql_fetch_row(MYSQL_RES* result)
  2. 说明:
  3. 1.mysql_store_result()之后使用时,如果没有要检索的行,mysql_fetch_row()返回NULL
  4. 2.mysql_use_result()之后使用时,如果没有要检索的行或出现了错误,
  5. mysql_fetch_row()返回NULL
  6. 3.行内值的数目由mysql_num_fields(result)给出。如果行中保存了调用
  7. mysql_fetch_row()返回的值,将按照row[0]到row[mysql_num_fields(result)-1],
  8. 访问这些值的指针。
  9. 4.可以通过调用mysql_fetch_lengths()来获得行中字段值的长度。对于空字段以及
  10. 包含NULL的字段,长度为0。通过检查字段值的指针,能够区分它们。如果指针为NULL
  11. 字段为NULL,否则字段为空。
  12. 参数:是函数mysql_store_resultmysql_use_result的返回值
  13. 返回值:下一行的MYSQL_ROW结构。如果没有更多要检索的行或出现了错误,返回NULL
6.mysql_free_result函数:释放结果集

函数原型:

  1. void mysql_free_result(MYSQL_RES *result)
  2. 说明:释放由mysql_store_result()、mysql_use_result()、mysql_list_dbs()等为结果
  3. 集分配的内存。完成对结果集的操作后,必须调用mysql_free_result()释放结果集使用的内存。
7.mysql_close函数:关闭数据库连接

函数原型:

  1. void mysql_close(MYSQL *mysql)
  2. 说明:关闭前面打开的连接。如果句柄是由mysql_init()或mysql_connect()自动分配的,
  3. mysql_close()还将解除分配由mysql指向的连接句柄。
8.mysql_num_fields(MYSQL_RES*):该函数可以拿表中的列数,返回值是一个unsigned类型

函数原型:

  1. unsigned int STDCALL mysql_num_fields(MYSQL_RES *res);
9.mysql_fetch_fields(MYSQL_RES*): 该函数可以拿到表中每一列的字段名,返回的是一个结构体数组

函数原型:

  1. MYSQL_FIELD *STDCALL mysql_fetch_fields(MYSQL_RES *res);
10.mysql_fetch_lengths(MYSQL_RES*):该函数拿到行中每一列的字段长度,返回结果是一个unsigned类型

函数原型:

  1. unsigned long *STDCALL mysql_fetch_lengths(MYSQL_RES *result);
11.mysql_field_count函数:返回最近查询的列数 。

函数原型:

  1. unsigned int mysql_field_count(MYSQL *mysql)
  2. 说明:此函数的正常用法是当返回 mysql_store_result() 时(因此您没有结果集) 指针)。
  3. 在这种情况下,您可以调用 mysql_field_count() 确定 mysql_store_result()
  4. 是否应 产生了非空的结果

5.事务设置:

在mysql中事务是默认自动提交的,如果需要提交的事务多,对我们的操作会有影响,所以需要设置事务为手动提交

  • mysql_autocommit(MYSQL* , mode) 设置事务是否自动提交函数

参数:mode如果为“1”,自动提交,为“0”为手动提交 返回值:提交成功返回0,否则返回非0

  • mysql_commit(MYSQL* mysql) 事务提交函数

返回值:成功返回0,否则返回非0

  • mysql_rollback(MYSQL* mysql) 事务回滚函数

返回值:成功返回0,否则返回非0

6.打印错误信息:

  • const char* mysql_error(MYSQL* mysql):返回错误信息的描述

  • const char* mysql_errno(MYSQL* mysql):返回错误的编号

代码使用的例子

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include<iostream>
  3. #include<mysql.h>
  4. usingnamespace std;
  5. intmain(){
  6. //创建句柄
  7. MYSQL mysql;
  8. //创建数据集变量
  9. MYSQL_RES* res = nullptr;
  10. //创建结果集变量
  11. MYSQL_ROW row;
  12. //创建一个结构体
  13. MYSQL_FIELD* field;
  14. //初始化数据库句柄
  15. mysql_init(&mysql);
  16. //设置字符集
  17. //mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk");
  18. mysql_set_character_set(&mysql, "gbk");
  19. //开始连接数据库
  20. if (mysql_real_connect(&mysql, "localhost", "root", "Z20020803", "box_man", 3306, NULL, 0))
  21. {
  22. cout << "连接成功" << endl;
  23. }
  24. else
  25. {
  26. cout << "连接失败" << endl;
  27. return0;
  28. }
  29. //设置事务
  30. mysql_autocommit(&mysql, "1");
  31. //增加数据
  32. string str1 = "insert into tb_912 values(2, 'xiaoming', '李四');";
  33. char ssql[1024];
  34. //使用sprintf拼出来的语句是一个标准的c语言字符串,可以使用该函数插入变量值
  35. sprintf(ssql, "insert into tb_912 values(%d, '%s', '%s');", 3, "daming", "17777777772");
  36. if (mysql_query(&mysql, ssql))//该语句提交成功返回0,失败返回1
  37. {
  38. cout << "提交失败" << endl;
  39. }
  40. else
  41. {
  42. cout << "提交成功" << endl;
  43. }
  44. //提交语句
  45. mysql_query(&mysql, str1.c_str());
  46. //删除数据
  47. string str3 = "delete from tb_912 where id = 2";
  48. mysql_query(&mysql, str3.c_str());
  49. //修改数据
  50. string str4 = "update tb_912 set name = '张三' where id = 1";
  51. mysql_query(&mysql, str4.c_str());
  52. //查询数据
  53. string str2 = "select * from tb_912";
  54. mysql_query(&mysql, str2.c_str());
  55. //事务提交
  56. mysql_commit(&mysql);
  57. //获取里面的结果集
  58. res = mysql_store_result(&mysql);
  59. //拿到结果集得列数,调用的是 mysql_store_result() 的返回值,
  60. unsignedint a = mysql_num_fields(res);
  61. cout <<"表得列数:"<< a << endl;
  62. //使用 mysql_fetch_fields() 函数获取列的名字,返回的是一个结构体数组
  63. field = mysql_fetch_fields(res);
  64. for (unsigned i = 0; i < a; i++)
  65. {
  66. cout << "当前列的名字:" << field[i].name << endl;//取出名字
  67. }
  68. unsignedlong* lengths;
  69. //从结果集中获取到数据 mysql_fetch_row() 获取结果集中的一行数据,
  70. //成功:返回记录当前行中每个字段的值,失败:返回一个null
  71. while (row = mysql_fetch_row(res))
  72. {
  73. printf("%s %s %s \n", row[0], row[1], row[2]);
  74. //获取列中字段的长度
  75. lengths = mysql_fetch_lengths(res);//返回的是一个数组地址
  76. for (unsignedint i = 0; i < a; i++)
  77. {
  78. cout << "当前列的长度:" << lengths[i] << endl;//列数会构成一个数组
  79. }
  80. }
  81. //释放结果集
  82. mysql_free_result(res);
  83. //关闭mysql实例
  84. mysql_close(&mysql);
  85. return0;
  86. }

多条语句提交的代码实现

  1. #include<iostream>
  2. #include<mysql.h>
  3. #include<thread>
  4. #include<sstream>
  5. #include<map>
  6. using namespace std;
  7. int main()
  8. {
  9. //1.创建句柄
  10. MYSQL mysql;
  11. //2.初始化mysql
  12. mysql_init(&mysql);
  13. const char* host = "127.0.0.1";
  14. const char* user = "root";
  15. const char* pwd = "Z20020803";
  16. const char* db = "database1";
  17. //设定字符集
  18. mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk");
  19. //3.连接数据库
  20. //一次性执行多条语句,mysql_real_connect 函数的最后一个参数设置
  21. if (!mysql_real_connect(&mysql, host, user, pwd, db, 3306, 0, CLIENT_MULTI_STATEMENTS))//阻塞函数
  22. {
  23. cout << "connect fail, " << mysql_error(&mysql) << endl;
  24. }
  25. else
  26. {
  27. cout << "mysql connect " << host << "success" << endl;
  28. }
  29. //1.创建表
  30. string sql = "CREATE TABLE IF NOT EXISTS t_image (\
  31. id int AUTO_INCREMENT,\
  32. name varchar(1024),\
  33. path varchar(1024),\
  34. size int,\
  35. PRIMARY KEY(id)\
  36. );";
  37. //2.删除数据
  38. sql += "truncate t_image;";
  39. //3.插入数据
  40. for (int i = 0; i < 1000; i++)
  41. {
  42. //sql = "insert t_image (name, path, size) values ('test.jpg', 'd:/img/test.jpg', 1024)";
  43. stringstream ss;//用于拼接字符串
  44. ss << "insert t_image (name, path, size) values ('image";
  45. ss << i << ".jpg', 'd:/image/',1024);";
  46. sql += ss.str();
  47. }
  48. //4.修改数据
  49. sql += "update t_image set name = 'test3.png', size = 100 where id = 3;";
  50. //5.删除数据
  51. sql += "delete from t_image where id = 1;";
  52. //6.查询数据
  53. sql += "select * form t_image;";
  54. //执行sql语句会立刻返回,但在数据库中是没有执行好的,需要获取结果
  55. int re = mysql_query(&mysql, sql.c_str());//只提交一次
  56. if (re == 0)
  57. {
  58. int count = mysql_affected_rows(&mysql);
  59. cout << "mysql_affected_rows " << count << "id = " << mysql_insert_id(&mysql) << endl;
  60. }
  61. else
  62. {
  63. cout << "mysql_query failed " << mysql_error(&mysql) << endl;
  64. }
  65. //多个返回结果
  66. do {
  67. MYSQL_RES* result = mysql_store_result(&mysql);
  68. if (result)
  69. {
  70. cout << "有select数据,行数:" << mysql_num_rows(result) << endl;
  71. mysql_free_result(result);//释放结果集
  72. }
  73. else//INSERT UPDATE DELETE CREATE DROP truncate
  74. {
  75. if (mysql_field_count(&mysql) > 0)//select 是否为空
  76. {
  77. cout << "Not retrieve result!" << mysql_error(&mysql) << endl;
  78. }
  79. else//INSERT UPDATE DELETE CREATE DROP truncate
  80. {
  81. //等待执行结果集
  82. cout << mysql_affected_rows(&mysql) << " rows affectd" << endl;
  83. }
  84. }
  85. } while (mysql_next_result(&mysql) == 0);//表示还有下一条结果
  86. mysql_close(&mysql);
  87. mysql_library_end();
  88. getchar();
  89. return 0;
  90. }

图片的插入及获取

  1. #include<iostream>
  2. #include<mysql.h>
  3. #include<thread>
  4. #include<sstream>
  5. #include<map>
  6. #include<chrono>
  7. #include<fstream>
  8. using namespace std;
  9. using namespace chrono;
  10. int main()
  11. {
  12. //1.创建句柄
  13. MYSQL mysql;
  14. //2.初始化mysql
  15. mysql_init(&mysql);
  16. const char* host = "127.0.0.1";
  17. const char* user = "root";
  18. const char* pwd = "Z20020803";
  19. const char* db = "database1";
  20. //设定字符集
  21. mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk");
  22. //3.连接数据库
  23. if (!mysql_real_connect(&mysql, host, user, pwd, db, 3306, 0, CLIENT_MULTI_STATEMENTS))//阻塞函数
  24. {
  25. cout << "connect fail, " << mysql_error(&mysql) << endl;
  26. }
  27. else
  28. {
  29. cout << "mysql connect " << host << "success" << endl;
  30. }
  31. //1.创建表 使用了二进制的blob类型
  32. string sql = "CREATE TABLE IF NOT EXISTS t_data (\
  33. id int AUTO_INCREMENT,\
  34. name varchar(1024),\
  35. data blob,\
  36. size int,\
  37. PRIMARY KEY(id)\
  38. )ENGINE=InnoDB;";
  39. int re = mysql_query(&mysql, sql.c_str());
  40. if (re != 0)
  41. {
  42. cout << mysql_error(&mysql) << endl;
  43. }
  44. //2.清空表
  45. sql = "truncate t_data";
  46. re = mysql_query(&mysql, sql.c_str());
  47. if (re != 0)
  48. {
  49. cout << mysql_error(&mysql) << endl;
  50. }
  51. //3..创建stmt对象
  52. MYSQL_STMT* stmt = mysql_stmt_init(&mysql);
  53. if (!stmt)
  54. {
  55. cout << "mysql_stmt_init " << mysql_error(&mysql) << endl;
  56. }
  57. //4.预处理sql语句
  58. sql = "INSERT INTO t_data (name, data, size) VALUES(?,?,?)";
  59. if (mysql_stmt_prepare(stmt, sql.c_str(), sql.size()))
  60. {
  61. cerr << "mysql_stmt_prepare failed" << mysql_stmt_error(stmt) << endl;
  62. }
  63. //使用c++方式打开文件,也可以使用c语言的方式打开文件
  64. //5.打开文件
  65. string filename = "1.jpg";
  66. //文件大小和文件二进制地址
  67. int filesize = 0;
  68. //读取二进制
  69. fstream in(filename, ios::in | ios::binary);
  70. if (!in.is_open())
  71. {
  72. cerr << "file " << filename << " open failed!" << endl;
  73. }
  74. //文件指针移动到结尾处
  75. in.seekg(0, ios::end);
  76. //文件大小和文件二进制地址
  77. filesize = in.tellg();
  78. //文件指针回到开头
  79. in.seekg(0, ios::beg);
  80. //读取数据
  81. char* data = new char[filesize];
  82. int readed = 0;//已经读了多少
  83. while (!in.eof())
  84. {
  85. in.read(data + readed, filesize - readed);
  86. //读取了多少字节
  87. if (in.gcount() <= 0)
  88. {
  89. break;
  90. }
  91. readed += in.gcount();
  92. }
  93. in.close();
  94. //6.绑定字段
  95. MYSQL_BIND bind[3] = { 0 };
  96. bind[0].buffer_type = MYSQL_TYPE_STRING; //name 文件名
  97. bind[0].buffer = (char*)filename.c_str();
  98. bind[0].buffer_length = filename.size();
  99. bind[1].buffer_type = MYSQL_TYPE_BLOB;
  100. bind[1].buffer = data;
  101. bind[1].buffer_length = filesize;
  102. //文件大小
  103. bind[2].buffer_type = MYSQL_TYPE_LONG;
  104. bind[2].buffer = &filesize;
  105. //绑定stmt对象
  106. if (mysql_stmt_bind_param(stmt, bind) != 0)
  107. {
  108. cerr << "mysql_stmt_bind_param failed" << mysql_stmt_error(stmt) << endl;
  109. }
  110. //7.执行stmt sql
  111. if (mysql_stmt_execute(stmt) != 0)
  112. {
  113. cerr << "mysql_stmt_execute failed" << mysql_stmt_error(stmt) << endl;
  114. }
  115. delete data;
  116. mysql_stmt_close(stmt);
  117. //获取数据
  118. sql = "select * from t_data";
  119. re = mysql_query(&mysql, sql.c_str());
  120. if (re != 0)
  121. {
  122. cout << "mysql_store_result failed" << mysql_error(&mysql) << endl;
  123. }
  124. //获取结果集
  125. MYSQL_RES* res = mysql_store_result(&mysql);
  126. if (res == NULL)
  127. {
  128. cerr << "mysql_store_result failed" << mysql_error(&mysql) << endl;
  129. }
  130. //取一行数据
  131. MYSQL_ROW row = mysql_fetch_row(res);
  132. if (!row)
  133. {
  134. cerr << "mysql_fetch_row failed" << mysql_error(&mysql) << endl;
  135. }
  136. cout << row[0] << " " << row[1] << " " << row[2] << endl;
  137. //获取每一列字段的长度
  138. unsigned long* lens = mysql_fetch_lengths(res);
  139. int fnum = mysql_num_fields(res);//获取每一列的字段长度
  140. filename = "out_";
  141. filename += row[1];
  142. fstream out(filename, ios::out | ios::binary);
  143. if (!out.is_open())
  144. {
  145. cout << "open file " << filename << " failed" << endl;
  146. }
  147. out.write(row[2], lens[2]);
  148. out.close();
  149. mysql_close(&mysql);
  150. mysql_library_end();
  151. getchar();
  152. return 0;
  153. }

存储过程的创建和使用

  1. #include<iostream>
  2. #include<mysql.h>
  3. #include<thread>
  4. #include<sstream>
  5. #include<map>
  6. using namespace std;
  7. int main()
  8. {
  9. //1.创建句柄
  10. MYSQL mysql;
  11. //2.初始化mysql
  12. mysql_init(&mysql);
  13. const char* host = "127.0.0.1";
  14. const char* user = "root";
  15. const char* pwd = "Z20020803";
  16. const char* db = "database1";
  17. //设定字符集
  18. mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk");
  19. //3.连接数据库
  20. //一次性执行多条语句,mysql_real_connect 函数的最后一个参数设置
  21. if (!mysql_real_connect(&mysql, host, user, pwd, db, 3306, 0, CLIENT_MULTI_STATEMENTS))//阻塞函数
  22. {
  23. cout << "connect fail, " << mysql_error(&mysql) << endl;
  24. }
  25. else
  26. {
  27. cout << "mysql connect " << host << "success" << endl;
  28. }
  29. string sql = "";
  30. //1.创建存储过程
  31. sql = "CREATE PROCEDURE p_test(IN p_in INT, OUT p_out INT, INOUT p_inout INT)\
  32. BEGIN\
  33. select p_in, p_out, p_inout;\
  34. set p_in = 100, p_out = 200, p_inout = 300;\
  35. select p_in, p_out, p_inout;\
  36. END";
  37. int re = mysql_query(&mysql, sql.c_str());
  38. if (re != 0)
  39. {
  40. cout << mysql_error(&mysql) << endl;
  41. }
  42. //2.定义数据库的变量,并且赋值
  43. cout << "A = 1, B = 2, C = 3" << endl;
  44. sql = "SET @A=1;SET @B=2;SET @C=3;";
  45. re = mysql_query(&mysql, sql.c_str());
  46. if (re != 0)
  47. {
  48. cout << mysql_error(&mysql) << endl;
  49. }
  50. //需要获取结果集并且释放
  51. do
  52. {
  53. cout << "set affected " << mysql_affected_rows(&mysql) << endl;
  54. } while (mysql_next_result(&mysql) == 0);// 等于0表示还有结果,等于-1表示没有结果了,大于0表示出错
  55. //3.调用存储过程
  56. sql = "call p_test(@A,@B,@C)";
  57. re = mysql_query(&mysql, sql.c_str());
  58. if (re != 0)
  59. {
  60. cout << "select " << mysql_error(&mysql) << endl;
  61. }
  62. cout << "in proce:";
  63. do
  64. {
  65. MYSQL_RES* res = mysql_store_result(&mysql);
  66. if (!res)
  67. {
  68. continue;
  69. }
  70. //字段数量
  71. int fcount = mysql_num_fields(res);
  72. //打印结果集
  73. for (;;)
  74. {
  75. MYSQL_ROW row = mysql_fetch_row(res);
  76. if (!row)
  77. {
  78. break;
  79. }
  80. for (int i = 0; i < fcount; i++)
  81. {
  82. if (row[i])
  83. {
  84. cout << row[i] << " ";
  85. }
  86. else
  87. {
  88. cout << "NULL ";
  89. }
  90. }
  91. cout << endl;
  92. }
  93. mysql_free_result(res);
  94. } while (mysql_next_result(&mysql) == 0);
  95. //获取存储过程
  96. sql = "select @A,@B,@C";
  97. re = mysql_query(&mysql, sql.c_str());
  98. if (re != 0)
  99. {
  100. cout << mysql_error(&mysql) << endl;
  101. }
  102. MYSQL_RES* res1 = mysql_store_result(&mysql);
  103. MYSQL_ROW row = mysql_fetch_row(res1);
  104. int num = mysql_num_fields(res1);
  105. for (int i = 0; i < num; i++)
  106. {
  107. cout << row[i] << " ";
  108. }
  109. mysql_free_result(res1);
  110. mysql_close(&mysql);
  111. mysql_library_end();
  112. getchar();
  113. return 0;
  114. }
标签: http 服务器 前端

本文转载自: https://blog.csdn.net/weixin_62859191/article/details/128767283
版权归原作者 爱笑的蛐蛐 所有, 如有侵权,请联系我们删除。

“C++连接mysql(改进)”的评论:

还没有评论