当前位置:   article > 正文

使用C语言连接MySQL_c连接mysql数据库

c连接mysql数据库

目录

一、引入库

1.1 下载库文件

1.2 在项目中引入库

二、使用库

2.1 连接数据库

2.2 SQL请求

2.3 获取查询结果

2.4 使用案例


一、引入库

1.1 下载库文件

要使用C语言连接MySQL,需使用MySQL官网提供的库

MySQL :: Download Connector/C++icon-default.png?t=N7T8https://dev.mysql.com/downloads/connector/cpp/

上传到云服务器

下载完毕后将其上传到云服务器即可。下面将下载的库文件解压后存放在一个名为makeuse的目录中

进入解压后的目录中,可以看到有一个include子目录和一个lib子目录

include目录下存放的是一批头文件

lib目录下存放的是动静态库

1.2 在项目中引入库

为了方便在项目中使用刚才的库文件,可以在项目目录下创建两个软连接,分别连接到刚才的include目录和lib目录

此时在项目目录下,就能直接看到刚才include和lib目录下的内容

下面先通过调用mysql_get_client_info来判断库是否引入成功,该函数的作用就是获取客户端的版本信息

  1. #include <iostream>
  2. #include <mysql.h>
  3. using namespace std;
  4. int main()
  5. {
  6. //获取客户端的版本信息
  7. cout<<"mysql client version: "<<mysql_get_client_info()<<endl;
  8. return 0;
  9. }

为了方便后续重复编译源文件,在项目目录下创建一个makefile

  1. mysqlConnect:mysqlConnect.cc
  2. g++ $^ -o $@ -std=c++11 -I./include -L./lib -lmysqlclient
  3. .PHONY:clean
  4. clean:
  5. rm -rf mysqlConnect
  • -I:指明头文件的搜索路径
  • -L:指明库文件的搜索路径
  • -l:指明需要连接库文件路径下的哪一个库

makefile编写完毕后,使用make命令编译代码生成可执行程序

但此时生成的可执行程序还不能直接运行,通过ldd命令可以发现,该可执行程序所依赖的mysqlclient库找不到

  • gcc/g++编译器默认都是动态链接,编译代码时默认使用动态库,所以生成的可执行程序在运行时需要找到对应的动态库进行链接,而使用的mysqlclient库并不在系统的搜索路径下
  • Makefile中的-I,-L和-l这三个选项,只是在编译期间告诉编译器头文件和库文件在哪里,而可执行程序生成后就与编译器无关了

动态库如何使用,在《Linux动静态库》这篇文章中讲解过,不知道如何配置的可以参考下面这篇文章

(28条消息) Linux动静态库_GG_Bond19的博客-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/GG_Bruse/article/details/128810497配置完成后可执行程序所依赖的mysqlclient库就能够被找到了

运行可执行程序后,可以看到客户端的版本为6.1.11,即刚才下载的库文件的版本

二、使用库

2.1 连接数据库

创建MySQL对象

MYSQL* mysql_init(MYSQL *mysql);
  • 该函数用来分配或者初始化一个MySQL对象,用于连接MySQL服务器
  • 若传入的参数是NULL,那么mysql_init将自动为你分配一个MySQL对象并返回
  • 若传入的参数是一个地址,那么mysql_init将在该地址处完成初始化

MYSQL对象中包含了各种信息,其类型定义如下: 

  1. typedef struct st_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_st *charset;
  7. MYSQL_FIELD *fields;
  8. MEM_ROOT field_alloc;
  9. my_ulonglong affected_rows;
  10. my_ulonglong insert_id; /* id if insert on table with NEXTNR */
  11. my_ulonglong 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. my_bool free_me; /* If free in mysql_close */
  24. my_bool reconnect; /* set to 1 if automatic reconnect */
  25. /* session-wide random string */
  26. char scramble[SCRAMBLE_LENGTH+1];
  27. my_bool unused1;
  28. void *unused2, *unused3, *unused4, *unused5;
  29. LIST *stmts; /* list of all statements */
  30. const struct st_mysql_methods *methods;
  31. void *thd;
  32. /*
  33. Points to boolean flag in MYSQL_RES or MYSQL_STMT. We set this flag
  34. from mysql_stmt_close if close had to cancel result set of this object.
  35. */
  36. my_bool *unbuffered_fetch_owner;
  37. /* needed for embedded server - no net buffer to store the 'info' */
  38. char *info_buffer;
  39. void *extension;
  40. } MYSQL;

注意:MYSQL对象中的methods变量是一个结构体变量,该变量里面保存着很多函数指针,这些函数指针将会在数据库连接成功以后的各种数据操作中被调用

连接数据库

  1. MYSQL* mysql_real_connect(MYSQL *mysql, const char *host,
  2. const char *user,
  3. const char *passwd,
  4. const char *db,
  5. unsigned int port,
  6. const char *unix_socket,
  7. unsigned long clientflag);
  • mysql: 表示在连接数据库前,调用mysql_init函数创建的MySQL对象
  • host: 表示需要连接的MySQL服务器的IP地址,"127.0.0.1"表示连接本地MySQL服务器
  • user: 表示连接MySQL服务器时,所使用用户的用户名
  • passwd: 表示连接MySQL服务器时,所使用用户的密码
  • db: 表示连接MySQL服务器后,要使用的数据库
  • port: 表示连接的MySQL服务器,所对应的端口号
  • unix_socket: 表示连接时应该使用的套接字或命名管道,通常设置为NULL
  • clientflag: 可以设置为多个标志位的组合,表示允许特定的功能,通常设置为0

返回值:

  • 若连接数据库成功,则返回一个MySQL对象,该对象与第一个参数的值相同
  • 若连接数据库失败,则返回NULL

关闭数据库连接

void mysql_close(MYSQL *sock);
  • 该函数的参数,就是连接数据库前调用mysql_init创建的MySQL对象
  • 若传入的MySQL对象是mysql_init自动创建的,那么调用mysql_close时就会释放这个对象

2.2 SQL请求

下发SQL请求

int	mysql_query(MYSQL *mysql, const char *q);
  • mysql: 表示在连接数据库前,调用mysql_init函数创建的MySQL对象
  • q: 表示向MySQL服务器下发的SQL请求,SQL最后可以不带分号

返回值:返回值为0表示SQL执行成功,否则表示SQL执行失败

设置编码格式

连接数据库后,需统一客户端和服务器的编码格式,避免在数据交互过程中出现乱码

int mysql_set_character_set(MYSQL *mysql, const char *csname);
  • mysql: 表示在连接数据库前,调用mysql_init函数创建的MySQL对象
  • csname: 表示要设置的编码格式,如"utf8"

返回值:返回值为0表示设置成功,否则表示设置失败

2.3 获取查询结果

  • 对数据库中的数据进行增删改操作时,都只需调用mysql_query向服务器下发对应的SQL请求
  • 而对数据库中的数据进行查询操作时,除了需要调用mysql_query向服务器下发对应的查询SQL,还需获取查询结果

获取查询结果

MYSQL_RES* mysql_store_result(MYSQL *mysql);
  • 该函数会调用指定MySQL对象中对应的函数指针来获取查询结果,并将获取到的查询结果保存到MYSQL_RES变量中进行返回
  • MYSQL_RES变量的内存空间是malloc出来的,因此在使用完后需要调用free函数进行释放,否则会造成内存泄露
  1. typedef struct st_mysql_res {
  2. my_ulonglong row_count;
  3. MYSQL_FIELD *fields;
  4. 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 st_mysql_methods *methods;
  9. MYSQL_ROW row; /* If unbuffered read */
  10. MYSQL_ROW current_row; /* buffer to current row */
  11. MEM_ROOT field_alloc;
  12. unsigned int field_count, current_field;
  13. my_bool eof; /* Used by mysql_fetch_row */
  14. /* mysql_stmt_close() had to cancel this result */
  15. my_bool unbuffered_fetch_cancelled;
  16. void *extension;
  17. } MYSQL_RES;

获取查询结果的行数

该函数会从指定的MYSQL_RES对象中,获取查询结果的行数 

my_ulonglong mysql_num_rows(MYSQL_RES *res);

获取查询结果的列数

该函数会从指定的MYSQL_RES对象中,获取查询结果的列数

unsigned int mysql_num_fields(MYSQL_RES *res);

获取查询结果的列属性

该函数会从指定的MYSQL_RES对象中,获取查询结果的列属性

MYSQL_FIELD* mysql_fetch_fields(MYSQL_RES *res);

mysql_fetch_fields函数将会返回多个MYSQL_FIELD对象,每个MYSQL_FIELD对象中保存着对应列的各种列属性,其类型定义如下:

  1. typedef struct st_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;

获取查询结果中的一行数据

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);

MYSQL_ROW对象中保存着一行数据,这一行数据中可能包含多个字符串,对应就是这行数据中的多个列信息,因此MYSQL_ROW本质就是char**类型,其类型定义如下:

typedef char **MYSQL_ROW;		/* return data as array of strings */

2.4 使用案例

查询user表中的数据并进行打印输出

  1. #include <iostream>
  2. #include <string>
  3. #include <mysql.h>
  4. using namespace std;
  5. const string host = "43.139.44.157";
  6. const string passwd = "123qwe@@@QWE";
  7. const string user = "bjy";
  8. const string db = "olinejudge";
  9. const int port = 3306;
  10. int main()
  11. {
  12. //1、获取MySQL实例(相当于创建了一个MySQL句柄)
  13. MYSQL* ms = mysql_init(nullptr);
  14. //2、连接数据库
  15. if(mysql_real_connect(ms, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr) {
  16. cerr<<"数据库连接失败!"<<endl;
  17. return 1;
  18. }
  19. cout<<"数据库连接成功!"<<endl;
  20. mysql_set_character_set(ms, "utf8"); //设置编码格式为utf8
  21. //3、查询数据库表中的记录
  22. //a、执行查询语句
  23. string sql = "select * from user";
  24. if(mysql_query(ms, sql.c_str()) != 0) {
  25. cout<<"查询数据失败!"<<endl;
  26. return 2;
  27. }
  28. cout<<"查询数据成功!"<<endl;
  29. //b、获取查询结果
  30. MYSQL_RES* res = mysql_store_result(ms);
  31. int rows = mysql_num_rows(res); //行数
  32. int cols = mysql_num_fields(res); //列数
  33. //获取每列的属性并打印列名
  34. MYSQL_FIELD* fields = mysql_fetch_fields(res);
  35. for(int i = 0;i < cols;i++) cout<<fields[i].name<<"\t";
  36. cout<<endl;
  37. for(int i = 0;i < rows;i++) {
  38. //获取一行数据并进行打印
  39. MYSQL_ROW row = mysql_fetch_row(res);
  40. for(int j = 0;j < cols;j++) {
  41. cout<<row[j]<<"\t";
  42. }
  43. cout<<endl;
  44. }
  45. free(res); //释放内存空间
  46. //4、关闭数据库
  47. mysql_close(ms);
  48. cout<<"数据库关闭成功!"<<endl;
  49. return 0;
  50. }

使用make命令生成可执行程序,运行后在即可看到数据的查询结果

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/583898
推荐阅读
相关标签
  

闽ICP备14008679号