文章目录
要使用 C 语言连接 MySQL,我们需要做一些准备工作:
- 保证 MySQL 服务有效。
- 在 MySQL 官网上下载适合自己平台的 MySQL Connector/C 库。
对应的网址:https://downloads.mysql.com/archives/c-c/
把压缩包下载下来后,将其解压到当前目录。
进入解压后的目录后,可以看到该目录下的 include 目录和 lib 目录。
其中,include 目录下存放的是头文件(方法的声明),lib 目录下存放的是动静态库(方法的实现,打包成库)。
必须要让程序在运行时能找到上述的库文件!
为了验证库的引入是否成功,可以通过调用其中的mysql_get_client_info
函数来验证。
该函数的作用是获取 MySQL 客户端的版本信息。
#include #include #include int main(){ std::cout << "client version: " << mysql_get_client_info() << std::endl; return 0;}
运行结果:
程序成功运行,说明库已经成功被引入了,至此库的引入工作已经做完。
1. mysql_init
MYSQL *mysql_init(MYSQL *mysql);
mysql_init
函数的作用:创建一个 MYSQL 对象(该对象用于连接数据库)。
mysql_init
函数的参数:
① mysql:MYSQL 结构体指针,一般设置为 NULL 。
mysql_init
函数的返回值:
① 成功,返回一个指向 MYSQL 对象的指针。
② 失败,返回 NULL 。
MYSQL 对象的定义如下:
typedef struct st_mysql{ NETnet; unsigned char*connector_fd; char*host,*user,*passwd,*unix_socket,*server_version,*host_info; char *info, *db; struct charset_info_st *charset; MYSQL_FIELD*fields; MEM_ROOTfield_alloc; my_ulonglong affected_rows; my_ulonglong insert_id; my_ulonglong extra_info; unsigned long thread_id; unsigned long packet_length; unsigned intport; unsigned long client_flag,server_capabilities; unsigned intprotocol_version; unsigned intfield_count; unsigned int server_status; unsigned int server_language; unsigned intwarning_count; struct st_mysql_options options; enum mysql_status status; my_boolfree_me; my_boolreconnect; char scramble[SCRAMBLE_LENGTH+1]; my_bool unused1; void *unused2, *unused3, *unused4, *unused5; LIST *stmts; const struct st_mysql_methods *methods; void *thd; my_bool *unbuffered_fetch_owner; char *info_buffer; void *extension;} MYSQL;
MYSQL 对象里有很多连接基本参数,它也包含了一个叫 st_mysql_methods 的结构体变量,该变量里面保存着很多函数指针,这些函数指针将会在数据库连接成功以后的各种数据操作中被调用。
2. mysql_real_connect
MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long clientflag);
mysql_real_connect
函数的作用:连接数据库。
mysql_real_connect
函数的参数:
① mysql:MYSQL 对象指针。
② host:要连接的 MySQL 服务器的 IP 地址。
③ user:用户名,以哪个用户身份连接。
④ passwd:用户密码。
⑤ db:要连接的数据库。
⑥ port:要连接的 MySQL 服务器的端口号。
⑦ unix_socket:通常设置为 NULL 。
⑧ clientflag:通常设置为 0 。
mysql_real_connect
函数的返回值:
① 成功,返回一个指向 MYSQL 对象的指针,与第一个参数 mysql 的值相同。
② 失败,返回 NULL 。
3. mysql_close
void mysql_close(MYSQL *sock);
mysql_close
函数的作用:关闭数据库连接。
mysql_close
函数的参数:
① sock:MYSQL 对象指针。
mysql_close
函数的返回值:无。
4. mysql_set_character_set
在连接数据库之后,需要先统一客户端和服务器的编码格式,避免在数据交互的过程中出现乱码。
int mysql_set_character_set(MYSQL *mysql, const char *csname);
mysql_set_character_set
函数的作用:设置编码格式。
mysql_set_character_set
函数的参数:
① mysql:MYSQL 对象指针。
② csname:要设置成哪种字符集。
mysql_set_character_set
函数的返回值:
① 成功,为 0 。
② 失败,为非 0 。
5. mysql_query
int mysql_query(MYSQL *mysql, const char *q);
mysql_query
函数的作用:下发 SQL 请求。
mysql_query
函数的参数:
① mysql:MYSQL 对象指针。
② q:要执行的 SQL 语句(语句结尾可以不带分号)。
mysql_query
函数的返回值:
① 成功,为 0 。
② 失败,为非 0 。
6. mysql_store_result
MYSQL_RES *mysql_store_result(MYSQL *mysql);
mysql_store_result
函数的作用:获取查询结果。
mysql_store_result
函数的参数:
① mysql:MYSQL 对象指针。
mysql_store_result
函数的返回值:
① 成功,返回一个指向 MYSQL_RES 对象的指针。
② 失败,返回 NULL 。
该函数会调用 MYSQL 变量中的 st_mysql_methods 中对应的函数指针来获取查询结果。
该函数会 malloc 出一个 MYSQL_RES 结构体变量,将获取到的查询结果保存到该变量中,最后返回该变量的指针。
由于 MYSQL_RES 的内存空间是 malloc 出来的,所以在使用完之后一定要记得调用 free 函数来释放对应的内存空间,否则会造成内存泄漏。
执行完mysql_store_result
以后,其实要查询的数据都已经在 MYSQL_RES 变量中了,下面的函数基本就是读取 MYSQL_RES 中的数据,参数都是 MYSQL_RES 对象指针:
// 获取结果的行数my_ulonglong mysql_num_rows(MYSQL_RES *res);// 获取结果的列数unsigned int mysql_num_fields(MYSQL_RES *res);// 获取结果的列属性MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);// 获取结果中的一行记录MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
关于mysql_fetch_row
函数的返回值 MYSQL_ROW:
MYSQL_ROW,即结果中的一行记录,对应着多个列信息,实际上就是一个字符串数组,因此,MYSQL_ROW 类型,本质就是 char** 类型,其定义如下:
typedef char **MYSQL_ROW;
1.连接数据库和关闭数据库连接
mysql_real_connect
和mysql_close
:
#include #include #include #include const std::string host = "127.0.0.1";const std::string user = "skc";const std::string password = "32aT.&6/1*hqrs/s";const std::string db = "102_db";const unsigned int port = 3306;int main(){ // std::cout << "client version: " << mysql_get_client_info() << std::endl; //0. 创建mysql句柄 MYSQL *my = mysql_init(nullptr); //1. 连接数据库 if(mysql_real_connect(my, host.c_str(), user.c_str(), password.c_str(), db.c_str(), port, nullptr, 0) == nullptr){ std::cout << "connect failed" << std::endl; return 1; } std::cout << "connect success" << std::endl; //2. 访问数据库 //3. 关闭数据库连接 mysql_close(my); return 0;}
运行结果:
2.访问数据库
mysql_query
:
- 执行 insert 操作:
#include #include #include #include const std::string host = "127.0.0.1";const std::string user = "skc";const std::string password = "32aT.&6/1*hqrs/s";const std::string db = "102_db";const unsigned int port = 3306;int main(){ // std::cout << "client version: " << mysql_get_client_info() << std::endl; //0. 创建mysql句柄 MYSQL *my = mysql_init(nullptr); //1. 连接数据库 if(mysql_real_connect(my, host.c_str(), user.c_str(), password.c_str(), db.c_str(), port, nullptr, 0) == nullptr){ std::cout << "connect failed" << std::endl; return 1; } //1.1: 需要设置连接的编码格式,否则会出现乱码 mysql_set_character_set(my, "utf8"); std::cout << "connect success" << std::endl; //2. 访问数据库 std::string sql = "insert into mytest values (4, \'猪八戒\')"; int res = mysql_query(my, sql.c_str()); if(res != 0){ std::cout << "execute: " << sql << " failed" << std::endl; return 2; } std::cout << "execute: " << sql << " success" << std::endl; //3. 关闭数据库连接 mysql_close(my); return 0;}
运行结果:
执行了 insert 操作。
- 执行 delete 操作:
std::string sql = "delete from mytest where id=3";
运行结果:
执行了 delete 操作。
- 执行 update 操作:
std::string sql = "update mytest set name=\'唐僧\' where id=2";
运行结果:
执行了 update 操作。
- 执行 select 操作:
#include #include #include #include const std::string host = "127.0.0.1";const std::string user = "skc";const std::string password = "32aT.&6/1*hqrs/s";const std::string db = "102_db";const unsigned int port = 3306;int main(){ // std::cout << "client version: " << mysql_get_client_info() << std::endl; //0. 创建mysql句柄 MYSQL *my = mysql_init(nullptr); //1. 连接数据库 if(mysql_real_connect(my, host.c_str(), user.c_str(), password.c_str(), db.c_str(), port, nullptr, 0) == nullptr){ std::cout << "connect failed" << std::endl; return 1; } //1.1: 需要设置连接的编码格式 mysql_set_character_set(my, "utf8"); std::cout << "connect success" << std::endl; //2. 访问数据库 // 增删改是最简单的,因为只要sql执行完毕就完了 // std::string sql = "insert into mytest values (4, \'猪八戒\')"; // std::string sql = "delete from mytest where id=3"; // std::string sql = "update mytest set name=\'唐僧\' where id=2"; //2.1 select 其实是最不好处理的!select sql执行完只是第一步,还需要对数据进一步解析 //std::string sql = "select * from mytest where id=4"; //std::string sql = "select name from mytest where id=4"; std::string sql = "select * from mytest"; int code = mysql_query(my, sql.c_str()); if(code != 0){ std::cout << "execute: " << sql << " failed" << std::endl; return 2; } std::cout << "execute: " << sql << " success" << std::endl; //2.2 解析数据 -- 获取行号和列号 MYSQL_RES *result = mysql_store_result(my); int rows = mysql_num_rows(result); int cols = mysql_num_fields(result); std::cout << "行数:" << rows << ",列数:" << cols << std::endl; //2.3 解析数据 -- 获取表中列名 -- 一般不用,仅仅是为了测试代码的完整性 MYSQL_FIELD *fields = mysql_fetch_fields(result); for(int i = 0; i < cols; i++){ std::cout << fields[i].name << "\t"; } std::cout << std::endl; //2.4 解析数据 -- 获取表中的数据 -- 重要 for(int i = 0; i < rows; i++){ MYSQL_ROW line = mysql_fetch_row(result); // 获取完整的一行记录(默认从前往后) for(int j = 0; j < cols; j++){ std::cout << line[j] << "\t"; // 将一行记录内部的多列字符串依次打印 } std::cout << std::endl; } free(result); // 释放内存空间 //3. 关闭数据库连接 mysql_close(my); return 0;}
运行结果:
对照命令行下的 select 操作,没问题。
来源地址:https://blog.csdn.net/m0_59938453/article/details/130438101