14.MySQL使用C语言连接
14.MySQL使用C语言连接
文章目录
- 引入库
- 下载库文件
- 在项目中使用库
- 使用库
- 连接数据库
- 创建MySQL对象
- 连接数据库
- 关闭数据库连接
- 连接示例
- 下发SQL请求
- 设置编码格式
- 测试表介绍
- 向数据库中插入数据
- 删除数据库中的数据
- 修改数据库中的数据
- 获取查询结果
- 获取查询结果的行数
- 获取查询结果的列数
- 获取查询结果的列属性
- 获取查询结果中的一行数据
- 查询示例
- 连接数据库
引入库
要使用C语言连接MySQL数据库,首先需要引入MySQL官方提供的开发库。这个库中包含了我们进行数据库操作所需要的各种头文件和动态链接库。通过这些资源,我们可以编写出能够与MySQL服务器进行通信的C程序。
在开始之前,确保你已经下载了适合你操作系统版本的MySQL Connector/C库。如果你是在Linux环境下工作,可以从MySQL官网下载对应的压缩包,并将其上传到你的云服务器上。例如,可以将下载的库文件存放在一个名为thirdPath
的目录下,以便后续管理和使用。
上传完成后,使用rz -E
命令将文件上传到服务器,接着利用tar
命令解压压缩包。为了方便后续的操作,建议将解压后的目录名称简化,这样在项目中引用时会更加直观。
进入解压后的目录后,你会看到两个重要的子目录:include
和lib
。其中,include
目录下存放的是各种头文件,而lib
目录下则是静态库和动态库文件。这些文件是我们在编写C语言程序时不可或缺的部分。
在项目中使用库
为了更方便地在项目中使用这些库文件,可以在项目目录下创建两个软链接,分别指向include
和lib
目录。这样一来,你就可以直接在项目目录下访问到所需的头文件和库文件。
接下来,我们可以通过调用mysql_get_client_info
函数来验证库是否成功引入。该函数的作用是获取客户端的版本信息。以下是一个简单的示例代码:
#include <stdio.h>
#include <mysql.h>int main() {printf("MySQL client version: %s\n", mysql_get_client_info());return 0;
}
为了让编译过程更加便捷,建议在项目目录下创建一个Makefile。Makefile中的内容如下所示:
CC = gcc
CFLAGS = -Wall -I./include
LDFLAGS = -L./lib -lmysqlclientall: mainmain: main.o$(CC) $(CFLAGS) main.o $(LDFLAGS) -o mainmain.o: main.c$(CC) $(CFLAGS) -c main.cclean:rm -f *.o main
在这个Makefile中,-I
用于指定头文件的搜索路径,-L
用于指定库文件的搜索路径,而-l
则用于指明需要链接的库文件名称。
完成Makefile的编写后,通过make
命令即可编译生成可执行程序。然而,此时生成的可执行程序还不能直接运行,因为系统默认的动态库搜索路径中没有包含我们使用的mysqlclient
库。
解决这个问题的方法有几种:
- 将库文件拷贝到系统默认的库文件搜索路径
/lib64
。 - 将库文件所在的目录路径添加到
LD_LIBRARY_PATH
环境变量中。 - 将库文件所在的目录路径保存到以.conf为后缀的配置文件中,然后将该文件拷贝到
/etc/ld.so.conf.d/
目录下,并使用ldconfig
命令对配置文件进行更新。
在这里,我们选择第三种方法。具体步骤如下:
- 创建一个新的配置文件,比如
mysql.conf
。 - 将库文件所在的目录路径写入该配置文件中。
- 将
mysql.conf
文件复制到/etc/ld.so.conf.d/
目录下。 - 运行
ldconfig
命令更新动态链接库缓存。
完成上述步骤后,再次运行生成的可执行程序,你应该能看到客户端的版本信息,这表明库已经成功引入。
使用库
创建MySQL对象
在连接数据库之前,首先需要创建一个MySQL对象。这个对象将用于与MySQL服务器进行交互。创建MySQL对象的函数如下:
MYSQL* mysql_init(MYSQL *mysql);
该函数用于分配或初始化一个MySQL对象。如果传入的参数是NULL
,函数会自动为你分配一个MySQL对象并返回;如果传入的参数是一个地址,函数将在该地址处帮你完成初始化。
连接数据库
创建完MySQL对象后,就可以连接数据库了。连接数据库的函数如下:
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
:表示在连接数据库前调用mysql_init
函数创建的MySQL对象。host
:表示需要连接的MySQL服务器的IP地址。user
:表示连接MySQL服务器时所使用用户的用户名。passwd
:表示连接MySQL服务器时所使用用户的密码。db
:表示连接MySQL服务器后需要使用的数据库。port
:表示连接的MySQL服务器所对应的端口号。unix_socket
:表示连接时应该使用的套接字或命名管道,通常设置为NULL
。clientflag
:可以设置为多个标志位的组合,表示允许特定的功能,通常设置为0。
关闭数据库连接的函数如下:
void mysql_close(MYSQL *sock);
示例代码
下面是一个完整的示例代码,展示了如何连接数据库:
#include <stdio.h>
#include <string.h>
#include <mysql.h>const char host[] = "127.0.0.1";
const char user[] = "root";
const char passwd[] = "password";
const char db[] = "test_db";
const int port = 3306;int main() {// 1、创建MySQL对象MYSQL* ms = mysql_init(NULL);// 2、连接数据库if (mysql_real_connect(ms, host, user, passwd, db, port, NULL, 0) == NULL) {fprintf(stderr, "数据库连接失败! %s\n", mysql_error(ms));return 1;}printf("数据库连接成功!\n");// 3、关闭数据库mysql_close(ms);printf("数据库关闭成功!\n");return 0;
}
下发SQL请求
连接数据库后,就可以向MySQL服务器下发SQL请求了。下发SQL请求的函数如下:
int mysql_query(MYSQL *mysql, const char *q);
参数说明:
mysql
:表示在连接数据库前调用mysql_init
函数创建的MySQL对象。q
:表示向MySQL服务器下发的SQL请求。
在连接数据库之后,还需要设置编码格式,以避免数据交互过程中出现乱码。设置编码格式的函数如下:
int mysql_set_character_set(MYSQL *mysql, const char *csname);
参数说明:
mysql
:表示在连接数据库前调用mysql_init
函数创建的MySQL对象。csname
:表示要设置的编码格式,如"utf8"
。
测试表介绍
在与MySQL数据库交互时,假设我们有一个名为connect_demon
的数据库,其中包含一个user
表。表中有三条记录,分别是用户的信息。
向数据库中插入数据
在调用mysql_query
函数时,向MySQL服务器下发一条INSERT
SQL语句。例如:
#include <stdio.h>
#include <string.h>
#include <mysql.h>const char host[] = "127.0.0.1";
const char user[] = "root";
const char passwd[] = "password";
const char db[] = "test_db";
const int port = 3306;int main() {// 1、创建MySQL对象MYSQL* ms = mysql_init(NULL);// 2、连接数据库if (mysql_real_connect(ms, host, user, passwd, db, port, NULL, 0) == NULL) {fprintf(stderr, "数据库连接失败! %s\n", mysql_error(ms));return 1;}printf("数据库连接成功!\n");// 设置编码格式mysql_set_character_set(ms, "utf8");// 3、向数据库表中插入记录const char sql[] = "INSERT INTO user (id, name, age) VALUES (4, '赵六', 25)";if (mysql_query(ms, sql) != 0) {printf("插入数据失败! %s\n", mysql_error(ms));return 2;}printf("插入数据成功!\n");// 4、关闭数据库mysql_close(ms);printf("数据库关闭成功!\n");return 0;
}
删除数据库中的数据
同样地,调用mysql_query
函数并向MySQL服务器下发一条DELETE
SQL语句。例如:
#include <stdio.h>
#include <string.h>
#include <mysql.h>const char host[] = "127.0.0.1";
const char user[] = "root";
const char passwd[] = "password";
const char db[] = "test_db";
const int port = 3306;int main() {// 1、创建MySQL对象MYSQL* ms = mysql_init(NULL);// 2、连接数据库if (mysql_real_connect(ms, host, user, passwd, db, port, NULL, 0) == NULL) {fprintf(stderr, "数据库连接失败! %s\n", mysql_error(ms));return 1;}printf("数据库连接成功!\n");// 设置编码格式mysql_set_character_set(ms, "utf8");// 3、删除数据库表中的记录const char sql[] = "DELETE FROM user WHERE id=4";if (mysql_query(ms, sql) != 0) {printf("删除数据失败! %s\n", mysql_error(ms));return 2;}printf("删除数据成功!\n");// 4、关闭数据库mysql_close(ms);printf("数据库关闭成功!\n");return 0;
}
修改数据库中的数据
调用mysql_query
函数并向MySQL服务器下发一条UPDATE
SQL语句。例如:
#include <stdio.h>
#include <string.h>
#include <mysql.h>const char host[] = "127.0.0.1";
const char user[] = "root";
const char passwd[] = "password";
const char db[] = "test_db";
const int port = 3306;int main() {// 1、创建MySQL对象MYSQL* ms = mysql_init(NULL);// 2、连接数据库if (mysql_real_connect(ms, host, user, passwd, db, port, NULL, 0) == NULL) {fprintf(stderr, "数据库连接失败! %s\n", mysql_error(ms));return 1;}printf("数据库连接成功!\n");// 设置编码格式mysql_set_character_set(ms, "utf8");// 3、修改数据库表中的记录const char sql[] = "UPDATE user SET age=22 WHERE id=1";if (mysql_query(ms, sql) != 0) {printf("修改数据失败! %s\n", mysql_error(ms));return 2;}printf("修改数据成功!\n");// 4、关闭数据库mysql_close(ms);printf("数据库关闭成功!\n");return 0;
}
获取查询结果
对于数据库中的数据进行增删改操作时,只需要调用mysql_query
向服务器下发对应的SQL请求。而对于查询操作,则需要额外获取查询结果。
获取查询结果的函数如下:
MYSQL_RES* mysql_store_result(MYSQL *mysql);
该函数会调用指定MySQL对象中对应的函数指针来获取查询结果,并将获取到的查询结果保存到MYSQL_RES
变量中进行返回。需要注意的是,MYSQL_RES
变量的内存空间是通过malloc
分配的,因此在使用完后需要调用free
函数进行释放,否则会造成内存泄漏。
获取查询结果的行数和列数
获取查询结果的行数和列数的函数如下:
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);
查询示例
下面是一个完整的查询示例,展示如何查询user
表中的数据并进行打印输出:
#include <stdio.h>
#include <string.h>
#include <mysql.h>const char host[] = "127.0.0.1";
const char user[] = "root";
const char passwd[] = "password";
const char db[] = "test_db";
const int port = 3306;int main() {// 1、获取MySQL实例MYSQL* ms = mysql_init(NULL);// 2、连接数据库if (mysql_real_connect(ms, host, user, passwd, db, port, NULL, 0) == NULL) {fprintf(stderr, "数据库连接失败! %s\n", mysql_error(ms));return 1;}printf("数据库连接成功!\n");// 设置编码格式mysql_set_character_set(ms, "utf8");// 3、查询数据库表中的记录const char sql[] = "SELECT * FROM user";if (mysql_query(ms, sql) != 0) {printf("查询数据失败! %s\n", mysql_error(ms));return 2;}printf("查询数据成功!\n");// 获取查询结果MYSQL_RES* res = mysql_store_result(ms);int rows = mysql_num_rows(res); // 数据的行数int cols = mysql_num_fields(res); // 数据的列数// 获取每列的属性并打印列名MYSQL_FIELD* fields = mysql_fetch_fields(res);for (int i = 0; i < cols; i++) {printf("%s\t", fields[i].name);}printf("\n");for (int i = 0; i < rows; i++) {// 获取一行数据并进行打印MYSQL_ROW row = mysql_fetch_row(res);for (int j = 0; j < cols; j++) {printf("%s\t", row[j]);}printf("\n");}// 释放内存空间free(res);// 4、关闭数据库mysql_close(ms);printf("数据库关闭成功!\n");return 0;
}