14.MySQL用C语言连接

1.mysql_init 初始化数据库

MYSQL *mysql_init(MYSQL *mysql);

作用:

  • 初始化一个 MySQL 连接句柄

  • 为后续连接数据库做准备。

参数说明:

  • 通常传 nullptr(即 NULL),表示由函数内部自动分配并初始化一个 MYSQL 结构体。

  • 你也可以传一个已存在的 MYSQL* 指针,但这较少用,主要用于多连接复用。

返回值:

  • 成功:返回一个初始化后的 MYSQL* 指针(你之后要用这个指针连接、操作数据库)。

  • 失败:返回 nullptr(说明内存分配失败了)。

    MYSQL *conn = mysql_init(nullptr);
    if (!conn) {
    std::cerr << "Failed to init MySQL.\n";
    return 1;
    }

相当于文件描述符*FILE

2.mysql_close 关闭数据库

void mysql_close(MYSQL *mysql);

作用:

  • 关闭 MySQL 数据库连接

  • 释放资源(包括内部缓冲区、网络连接、内存等)。

参数说明:

  • 传入的是你用 mysql_init() 得到的 MYSQL* 指针。

即使你没成功连接,也推荐调用 mysql_close() 来释放 mysql_init() 分配的资源,保持代码整洁、稳定。

3.mysql_real_connect 连接数据库

复制代码
MYSQL *mysql_real_connect(
    MYSQL *mysql,           // mysql_init 返回的 MYSQL 指针
    const char *host,       // 主机地址,如 "localhost" 或 IP
    const char *user,       // 用户名
    const char *passwd,     // 密码
    const char *db,         // 要连接的数据库名(可为 NULL)
    unsigned int port,      // 端口号(MySQL 默认是 3306)
    const char *unix_socket,// 通常传 NULL,除非你用 socket 文件连接
    unsigned long client_flag // 一般传 0,或如 CLIENT_MULTI_STATEMENTS
);
  • 成功:返回的是 MYSQL*,也就是 conn 本身。

  • 失败:返回 NULL,你应该调用 mysql_error() 打印错误信息。

4.mysql_set_character_set 设置字符串集

int mysql_set_character_set(MYSQL *mysql, const char *csname);

参数名 类型 说明
mysql MYSQL* 已连接的 MySQL 对象指针(mysql_real_connect() 返回的)
csname const char* 要设置的字符集名称,如 "utf8""utf8mb4""gbk"
  • 0 表示设置成功;

  • 0 表示失败,可使用 mysql_error() 获取错误信息。

如果要处理中文字符 需要设置字符串集mysql_set_character_set(my,"utf8")

常见字符集 用途
utf8 常见 UTF-8(最多3字节)
utf8mb4 完整 UTF-8(最多4字节,支持 emoji)✅ 推荐
gbk 中文简体编码(兼容老系统)
latin1 默认西欧编码(默认值,不建议)

5.mysql_query 向数据库发SQL语句

int mysql_query(MYSQL *mysql, const char *query);

参数名 类型 含义
mysql MYSQL* 通过 mysql_init()mysql_real_connect() 获得的连接句柄
query const char* 要执行的 SQL 语句(字符串)
  • 0 表示设置成功;

  • 0 表示失败,可使用 mysql_error() 获取错误信息。

insert update delete都能成功,select能成功 但select 查询的数据怎么获取打印出来?

获取打印select结果

1.mysql_store_result 返回结果集

MYSQL_RES *mysql_store_result(MYSQL *mysql);

mysql_store_result() 从服务器获取完整的查询结果 ,并将其缓存在本地内存返回一个 MYSQL_RES* 结果集指针,供你遍历。

返回值 说明
MYSQL_RES*(非空) 查询成功,有结果集,可以继续用 mysql_fetch_row() 读取
nullptr 查询失败或语句没有返回结果(如 INSERT),可用 mysql_error() 获取错误信息

MYSQL_RES:

MYSQL_RES 是 MySQL C API 中的一个结构体 类型,用来表示一次 SQL 查询(通常是 SELECT)返回的结果集。

复制代码
typedef struct st_mysql_res {
    my_ulonglong row_count;  // 行数
    unsigned int field_count; // 列数
    MYSQL_FIELD *fields;      // 字段信息(列名等)
    unsigned long *lengths;   // 每列值的长度
    MYSQL_ROWS *data;         // 所有数据的行链表
    ...
} MYSQL_RES;

2.mysql_num_rows 获取行数

my_ulonglong mysql_num_rows(MYSQL_RES *res);

获取结果集中总共的"行数"(记录数)

参数:

  • res:由 mysql_store_result() 返回的结果集指针

返回值:

  • 返回类型是 my_ulonglong(64位无符号整数)

  • 表示总行数,例如:查询结果有 5 行,返回 5

3.mysql_num_fields 获取列数

unsigned int mysql_num_fields(MYSQL_RES *res);

获取结果集的"列数"(字段数)

4.mysql_fetch_row 获取一行数据

MYSQL_ROW mysql_fetch_row(MYSQL_RES *res);

从结果集中一行一行地提取数据,每调用一次,就"读取下一行",遍历到最好时返回 nullptr

就像迭代器一样从头到尾遍历一次

返回值:

  • 返回一个 MYSQL_ROW,实质上是 char **

  • 表示当前这一行的所有列的值(字符串形式)

MYSQL_ROW 是 MySQL C API 中用来表示查询结果中的一行数据 的结构,本质上是一个 char** 类型(即:字符串数组)。

5.mysql_fetch_fields 获取属性信息数组

MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);

获取结果集的所有字段(列)的属性信息数组

返回一个 MYSQL_FIELD* 数组,每个元素表示一个字段
MYSQL_FIELD:

复制代码
typedef struct st_mysql_field {
    char *name;        // 字段名(如 "id")
    char *table;       // 所属表名
    char *db;          // 所属数据库名
    enum enum_field_types type;  // 字段类型(如 MYSQL_TYPE_LONG、MYSQL_TYPE_STRING)
    unsigned int length;         // 最大长度
    unsigned int flags;          // 属性(如是否为主键、是否可空)
    ...
} MYSQL_FIELD;
成员名 类型 作用说明
name char* 字段名称(如 "id", "name"
table char* 该字段所在的表名
db char* 该字段所属的数据库名
type 枚举 字段的数据类型(如 MYSQL_TYPE_STRING
length unsigned int 字段最大长度
flags unsigned int 标记属性(如 NOT_NULL_FLAG, PRI_KEY_FLAG

6.mysql_free_result 释放结果集内存

void mysql_free_result(MYSQL_RES *res);

为什么必须调用?

  • mysql_store_result() 会把整个查询结果加载进内存;

  • 这个内存在客户端分配(不是自动释放);

  • 所以你必须手动调用 mysql_free_result() 来清理它。

否则,反复执行查询后内存会越来越多,造成内存泄漏甚至崩溃

mysql简单使用

复制代码
#include <iostream>
#include <string>
#include <mysql/mysql.h>
const std::string host = "localhost";
const std::string user = "wws";
const std::string password = "root1234";
const std::string db = "conn";
const unsigned int port = 3306;

int main()
{
    // 1。初始化数据库 会分配并初始化一个 MYSQL 连接句柄
    MYSQL *my = mysql_init(nullptr);
    if (!my)
    {
        std::cerr << "init MySQL error" << std::endl;
        return 1;
    }
    //2.连接数据库 也会返回权柄==my
    if (mysql_real_connect(my, host.c_str(), user.c_str(), password.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
        std::cerr << "connect MySQL error: " << mysql_error(my) << std::endl;
        mysql_close(my);
        return 2;
    }
    //3.设置字符串集 支持中文
    mysql_set_character_set(my,"utf8");
    //4.向数据库发SQL语句
    std::string sql_in="insert into t_conn values(1,'王强','23912')";
    std::string sql_up="update t_conn set name='asd' where name='王强'";
    std::string sql_de="delete from t_conn where id=1";
    std::string sql_se="select * from t_conn";
    std::string&sql=sql_se;
    int n=mysql_query(my,sql.c_str());
    if(n==0) std::cout<<sql<<" success"<<std::endl;
    else
    {
        std::cerr <<sql<< " mysql_query error: " << mysql_error(my) << std::endl;
        mysql_close(my);
        return 3;
    }
    //打印结果集
    //1.获取结果集
    MYSQL_RES* res=mysql_store_result(my);
    //2.获取行数 列数
    int rows=mysql_num_rows(res);
    int fields=mysql_num_fields(res);
    //3.获取属性信息 添加表头
    MYSQL_FIELD* fields_array=mysql_fetch_field(res);
    for(int i=0;i<fields;i++)
    {
        std::cout<<fields_array[i].name<<"  ";
    }
    std::cout<<std::endl;
    //4.获取行数据 遍历内容
    for(int i=0;i<rows;i++)
    {
        MYSQL_ROW row=mysql_fetch_row(res);
        for(int j=0;j<fields;j++)
        {
            std::cout<<row[j]<<"  ";
        }
        std::cout<<std::endl;
    }
    //5.释放结果集内存
    mysql_free_result(res);
    
    mysql_close(my);
}
相关推荐
SeaTunnel4 分钟前
如何将SeaTunnel MySQL-CDC与Databend 高效整合?格式与方案全解析
数据库·mysql·开源·数据集成·seatunnel·databend
在肯德基吃麻辣烫6 分钟前
《Redis》持久化
数据库·redis·缓存
顾三殇21 分钟前
【自考】《计算机信息管理课程实验(课程代码:11393)》华师自考实践考核题型解析说明:C++ 与 mysql 实践题型与工具实践题分析
c++·mysql·华师自考实践考核题型分析
xiaolyuh12324 分钟前
基于binlog恢复误删除MySQL数据
数据库·mysql
Gauss松鼠会35 分钟前
GaussDB分布式数据库调优方法总结:从架构到实践的全链路优化指南
数据库·分布式·sql·database·gaussdb
码海漫游者838 分钟前
让Python成为你的网站引擎:Django全栈开发初体验!!!
数据库·python·其他·django
Databend42 分钟前
玩转 Databend UDF
数据库
曼汐 .1 小时前
数据库管理与高可用-PostgreSQL日常维护
数据库
小陈又菜1 小时前
SQL ConcurrencyControl(并发控制)
数据库·sql··并发控制
zqmattack1 小时前
SQL 注入:iBatis与修复
网络·数据库·sql