【MySQL系列】使用C语言连接MySQL

「前言」文章内容大致是使用C语言连接MySQL。

「归属专栏」MySQL

「主页链接」个人主页

「笔者」枫叶先生(fy)

目录

一、Connector/C使用

按照前面MySQL的安装流程,安装完MySQL,MySQL相应的连接相关的库也被下载下来了

查看动态库是否存在

bash 复制代码
ls /lib64/mysql/

查看MySQL相应的头文件是否存在

bash 复制代码
ls /usr/include/mysql

如果不存在,需要安装一下

sql 复制代码
 yum install -y mysql-devel

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

cpp 复制代码
#include <iostream>
#include <mysql/mysql.h>

int main()
{
    std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;
    return 0;
}

进行编译

bash 复制代码
g++ -o mysql mysql.cpp -L/lib64/mysql -lmysqlclient
  • -L:用于指定库文件的搜索路径
  • -l:用于指明需要连接库文件路径下的哪一个库(L的小写)

这些在动静态库那里都讲过了,不再解释

运行可执行程序后,可以看到客户端的版本号

至此库已经成功被引入,接下来就是库函数的使用了

二、MySQL的C接口介绍

2.1 连接MySQL

1、初始化

在连接数据库之前,需要先创建一个MySQL对象,进行初始化

该函数如下:

c 复制代码
MYSQL* mysql_init(MYSQL *mysql);

说明:

  • 该函数用来分配或者初始化一个MySQL对象
  • 如果传入参数为NULL,mysql_init将自动分配一个MYSQL对象(句柄)并返回
  • 如果传入的是一个MYSQL对象,该函数会对该对象进行初始化

MYSQL是一个结构体,定义如下:

2、连接数据库

初始化完毕之后,必须先链接数据库,才能进行后续操作(mysql网络部分是基于TCP/IP的)

连接数据库的函数如下:

c 复制代码
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地址,"127.0.0.1"表示连接本地MySQL服务器
  • user:表示连接MySQL服务器时,登录所使用的用户名
  • passwd:表示连接MySQL服务器时,登录所使用用户的密码
  • db:表示连接MySQL服务器后,需要使用的是哪一个数据库
  • port:表示连接的MySQL服务器,所对应的端口号
  • unix_socket:表示连接时应该使用的套接字或命名管道,通常设置为NULL
  • clientflag:可以设置为多个标志位的组合,表示允许特定的功能,通常设置为0

返回值

  • 如果连接数据库成功,则返回一个MYSQL对象(句柄),该对象与第一个参数mysql相同
  • 如果连接数据库失败,则返回NULL

3、关闭数据库连接

与数据库交互完毕后,需要关闭数据库连接

关闭数据库连接的函数如下:

c 复制代码
void mysql_close(MYSQL *sock);

说明:

  • 参数sock,就是连接数据库前调用mysql_init创建的MySQL对象,传入该对象即可

连接测试

代码如下:

cpp 复制代码
#include <iostream>
#include <string>
#include <mysql/mysql.h>
using namespace std;

const string host = "127.0.0.1";
const string user = "fengye";
const string password = "123123aa";
const string db = "test_db";
const int port = 3306;

int main()
{
    // 1.初始化
    MYSQL* my = mysql_init(nullptr);
    // 2.连接数据库
    if(mysql_real_connect(my, host.c_str(), user.c_str(), password.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
        cerr << "数据库连接失败!" << endl;
        return 1;
    }
    cout << "连接成功" << endl;
    // 3.关闭连接
    mysql_close(my);
    
    return 0;
}

进行编译运行,数据库连接成功

2.2 发送SQL请求

数据库连接成功了,就可以进行进行发送SQL请求了

设置编码格式

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

c 复制代码
int mysql_set_character_set(MYSQL *mysql, const char *csname);

说明:

  • 参数mysql:是mysql_init函数创建初始化的MYSQL对象
  • csname:表示要设置的编码格式,如"utf8"

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

注:设置链接原始默认字符集是latin1

发送SQL请求

下发SQL请求的函数如下:

c 复制代码
int	mysql_query(MYSQL *mysql, const char *q);

说明:

  • mysql:是mysql_init函数创建初始化的MYSQL对象
  • q: 表示向MySQL服务器下发的SQL请求,SQL最后可以不带分号,也可以带

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

向数据库中插入数据

cpp 复制代码
#include <iostream>
#include <string>
#include <mysql/mysql.h>
using namespace std;

const string host = "127.0.0.1";
const string user = "fengye";
const string password = "123123aa";
const string db = "test_db";
const int port = 3306;

int main()
{
    // 1.初始化
    MYSQL* my = mysql_init(nullptr);
    // 2.连接数据库
    if(mysql_real_connect(my, host.c_str(), user.c_str(), password.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
        cerr << "数据库连接失败!" << endl;
        return 1;
    }
    cout << "连接成功" << endl;

    // 设置编码格式
    mysql_set_character_set(my, "utf8");

    string sql = "insert into user (name, age) values ('王五', 19);";
    if(mysql_query(my, sql.c_str()) != 0)
    {
        cerr << sql << " failed." << endl;
        return 2;
    }
    cout << sql << " sucsess." << endl;
    // 3.关闭连接
    mysql_close(my);
    
    return 0;
}

编译运行

删除数据库中的数据

进行删除数据测试

编译运行

修改数据库中的数据

进行修改数据库数据测试

编译运行

2.3 获取结果集

  • 对数据库中的数据进行增删改操作时,都只需要调用mysql_query向服务器下发对应的SQL请求,即不需要返回结果
  • 对于数据库中的数据进行查询操作时,除了需要调用mysql_query向服务器下发对应的查询SQL,还需要获取查询结果,把MySQL服务器查到的数据获取过来

获取查询结果的函数如下:

c 复制代码
MYSQL_RES* mysql_store_result(MYSQL *mysql);

注:

  • 获取到的查询结果保存到MYSQL_RES变量中
  • 该函数malloc了一片内存空间来存储查询过来的数据,需要进行释放该空间,否则会造成内存泄漏

MYSQL_RES是一个结构体,定义如下:

释放结果集函数:

c 复制代码
void mysql_free_result(MYSQL_RES *result);

说明:参数传入结果集即可

获取结果集成功后,需要获取结果集的行数和列数,方便进行遍历数据

获取查询结果的行数

获取查询结果的行数的函数如下:

c 复制代码
my_ulonglong mysql_num_rows(MYSQL_RES *res);

获取查询结果的列数

获取查询结果的列数的函数如下:

c 复制代码
unsigned int mysql_num_fields(MYSQL_RES *res);

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

c 复制代码
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);

注:

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

获取列名

获取查询结果的列属性的函数如下:

c 复制代码
MYSQL_FIELD* mysql_fetch_fields(MYSQL_RES *res);

注:

  • 列属性也是需要进行特定获取的
  • 每个MYSQL_FIELD对象中保存着对应列的各种列属性
  • 我们需要获取列名称,即name

MYSQL_FIELD结构体定义如下:

遍历结果集类似于遍历二维数组

查询演示

cpp 复制代码
#include <iostream>
#include <string>
#include <mysql/mysql.h>
using namespace std;

const string host = "127.0.0.1";
const string user = "fengye";
const string password = "123123aa";
const string db = "test_db";
const int port = 3306;

int main()
{
    // 1.初始化
    MYSQL* my = mysql_init(nullptr);
    // 2.连接数据库
    if(mysql_real_connect(my, host.c_str(), user.c_str(), password.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
        cerr << "数据库连接失败!" << endl;
        return 1;
    }
    cout << "连接成功" << endl;

    // 设置编码格式
    mysql_set_character_set(my, "utf8");

    // string sql = "insert into user (name, age) values ('王五', 19);";
    // string sql = "delete from user where id=4";
    // string sql = "update user set age=66 where id=1";
    string sql = "select * from user";
    if(mysql_query(my, sql.c_str()) != 0)
    {
        cerr << sql << " failed." << endl;
        return 2;
    }
    cout << sql << " sucsess." << endl;

    // 获取结果集
    MYSQL_RES* res = mysql_store_result(my);
    int row = mysql_num_rows(res);   // 数据行数
    int col = mysql_num_fields(res); // 数据列数
    
    // 获取每列的属性,并打印
    MYSQL_FIELD* fields = mysql_fetch_field(res);
    for(int i = 0; i < col; ++i)
    {
        cout << fields[i].name << "\t";
    }
    cout << endl;

    // 遍历数据
    for(int i = 0; i < row; ++i)
    {
        // 获取每一行
        MYSQL_ROW rows = mysql_fetch_row(res);
        for(int j = 0; j < col; ++j)
        {
            cout << rows[j] << "\t";
        }
        cout << endl;
    }

    // 释放res
    mysql_free_result(res);

    // 3.关闭连接
    mysql_close(my);
    
    return 0;
}

编译运行,数据成功被获取出来

  • 再说一下结果集,结果集指向一个数组,数组里面存放的都是char**的指针
  • 使用mysql_fetch_row函数获取一行,返回的结果实际是char**,char**又指向一个char*的数组

    --------------------- END ----------------------
cpp 复制代码
「 作者 」 枫叶先生
「 更新 」 2023.9.14
「 声明 」 余之才疏学浅,故所撰文疏漏难免,
          或有谬误或不准确之处,敬请读者批评指正。
相关推荐
Heisenberg~34 分钟前
详解八大排序(五)------(计数排序,时间复杂度)
c语言·数据结构·排序算法
lb36363636364 小时前
分享一下arr的意义(c基础)(必看)(牢记)
c语言·知识点
南东山人6 小时前
一文说清:C和C++混合编程
c语言·c++
stm 学习ing6 小时前
FPGA 第十讲 避免latch的产生
c语言·开发语言·单片机·嵌入式硬件·fpga开发·fpga
mqiqe8 小时前
Python MySQL通过Binlog 获取变更记录 恢复数据
开发语言·python·mysql
工业甲酰苯胺8 小时前
MySQL 主从复制之多线程复制
android·mysql·adb
BestandW1shEs8 小时前
谈谈Mysql的常见基础问题
数据库·mysql
重生之Java开发工程师8 小时前
MySQL中的CAST类型转换函数
数据库·sql·mysql
教练、我想打篮球8 小时前
66 mysql 的 表自增长锁
数据库·mysql