【MySQL】:用C语言连接MySQL

发布于:2025-02-11 ⋅ 阅读:(21) ⋅ 点赞:(0)

朋友们、伙计们,我们又见面了,本期来给大家带来用C语言链接数据库的知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成!

C 语 言 专 栏:C语言:从入门到精通

数据结构专栏:数据结构

个  人  主  页 :stackY、

C + + 专 栏   :C++

Linux 专 栏  :Linux

​ 

目录

1. 下载MySQL开发包

1.1 官网下载

1.2 一键安装(推荐) 

1.3 验证引入是否成功

2. 接口介绍

2.1 初始化

2.2 关闭链接

2.3 链接数据库

2.4 下发命令

2.5 获取结果

2.5.1 获取结果行、列数

2.5.2 提取查询结果

2.5.3 获取列名


 

之前的内容我们都是使用的是命令行的SQL,本章节我们来用C语言来连接MySQL。

1. 下载MySQL开发包

1.1 官网下载

① 搜索mysql.com进入

② 点击DOWNLOADS下拉找到MySQL Community (GPL) Downloads »

③ 找到C API

④ 找到MySQL Connector/C++ 8.0

⑤ 找到对应的版本的mysql库点击下载

1.2 一键安装(推荐) 

在Ubuntu 22.04 安装MySQL开发包应使用 apt命令

① 更新软件包列表

sudo apt-get update

② 安装MySQL安装包

sudo apt-get install libmysqlclient-dev

这个安装包含了开发MySQL客户端应用程序所需的头文件和库。

执行过程会遇到下面这个情况,直接按enter即可

③ 查看安装后的头文件和库

ls /usr/include/mysql/

find /usr/lib -name 'libmysqlclient*.so*'

至此,我们就已经完成了MySQL开发包的安装。

1.3 验证引入是否成功

通过 mysql_get_client_info() 函数,来验证我们的引入是否成功

#include <iostream>
//
#include <mysql/mysql.h>

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

注意:因为g++编译时只会引入C/C++的内部库,所以对于MySQL库我们需要使用编译选项手动引入:

2. 接口介绍

关于连接库的函数都在MySQL官网中:https://dev.mysql.com/doc/c-api/9.2/en/c-api-function-reference.html

2.1 初始化

要使用库,必须先进行初始化操作,用到的接口是:

MYSQL *mysql_init(MYSQL *mysql);
#include <iostream>
#include <mysql/mysql.h>

int main()
{
    // 初始化
    MYSQL* my = mysql_init(nullptr);
    if(my == nullptr)
    {
        std::cerr << "init MySQL error" << std:: endl;
        return 1;
    }
    
    return 0; 
}

2.2 关闭链接

使用完库之后需要将连接关闭,需要用到的接口是: 

void mysql_close(MYSQL *sock);

2.3 链接数据库

初始化完成之后,就要对库进行链接,再进行后续的操作。(MySQL网络部分是基于TCP/IP的)

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);
#include <iostream>
#include <mysql/mysql.h>
#include <string>

const std::string host = "127.0.0.1";         // 主机
const std::string user = "***";               // 用户
const std::string passwd = "**************";  // 密码
const std::string db = "conn";                // 使用的库
const unsigned int port = 3306;               // 端口号


int main()
{
    // 初始化
    MYSQL* my = mysql_init(nullptr);
    if(my == nullptr)
    {
        perror("err: \n");
        //std::cerr << "init MySQL error" << std:: endl;
        return 1;
    }

    // 链接数据库
    if(mysql_real_connect(my,host.c_str(),user.c_str(),passwd.c_str(),db.c_str(),port,nullptr,0) == nullptr)
    {
        perror("err: \n");
        std::cerr << "connect MySQL error" << std:: endl;
        return 2;
    }
    std::cout << "connect success" << std::endl;
    mysql_close(my);
    return 0; 
}

2.4 下发命令

链接成功之后我们就可以下发指令了
int mysql_query(MYSQL *mysql, const char *q);

 第一个参数是我们之前初始化并链接的库,第二个参数是我们所要执行的SQL语句。

#include <iostream>
#include <mysql/mysql.h>
#include <string>

const std::string host = "127.0.0.1";         // 主机
const std::string user = "ywh";               // 用户
const std::string passwd = "YwhHkty.070407";  // 密码
const std::string db = "conn";                // 使用的库
const unsigned int port = 3306;               // 端口号


int main()
{
    // 初始化
    MYSQL* my = mysql_init(nullptr);
    if(my == nullptr)
    {
        perror("err: \n");
        //std::cerr << "init MySQL error" << std:: endl;
        return 1;
    }

    // 链接数据库
    if(mysql_real_connect(my,host.c_str(),user.c_str(),passwd.c_str(),db.c_str(),port,nullptr,0) == nullptr)
    {
        perror("err: \n");
        std::cerr << "connect MySQL error" << std:: endl;
        return 2;
    }
    std::cout << "connect success" << std::endl;

    // 执行命令
    // 这里可以使用增删改
    const std::string sql = "insert into user values(1, '张三', 18, '1234567')";
    int n = mysql_query(my, sql.c_str());
    if(n != 0)
    {
        std::cerr << "query error" << std::endl;
        return 3;
    }
    
    mysql_close(my);
    return 0; 
}

如果插入数据库的中文名称会出现乱码,那么需要对编码格式进行修改即可

//建立好链接之后,获取英文没有问题,如果获取中文是乱码:
//设置链接的默认字符集是utf8,原始默认是latin1
mysql_set_character_set(myfd, "utf8");

2.5 获取结果

sql执行完以后,如果是查询语句,我们当然还要读取数据,如果update,insert等语句,那么就看下操作成功与否即可。

我们来看看如何获取查询结果: 如果mysql_query返回成功,那么我们就通过
mysql_store_result这个函数来读取结果。原型如下:

MYSQL_RES *mysql_store_result(MYSQL *mysql);

关于这个MYSQL_RES我们来详细的介绍一下:

当我们使用select语句查询结果时,显示的是一张表,虽然看起来是一张表,但是实际MySQL在读取的时候,全部都当做了字符串,那么mysql_store_result函数就会读取这些字符串,保存在RES中,其实RES就类似于一种二维指针数组一样。

所以我们就可以通过遍历数组的方式来访问RES来获取我们要的结果。

因为他是一个表结构,所以我们需要知道他有多少行有多少列,所以需要用到下面的一些接口。

2.5.1 获取结果行、列数

// 获取行数
my_ulonglong mysql_num_rows(MYSQL_RES *res);
// 获取列数
my_ulonglong mysql_num_fields(MYSQL_RES *res);

2.5.2 提取查询结果

那么如何对这些结果进行提取呢?

需要用到:

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);

她的返回值是MYSQL_ROW,其实就是一个char**类型,也就相当于二维数组了。

#include <iostream>
#include <mysql/mysql.h>
#include <string>

const std::string host = "127.0.0.1";         // 主机
const std::string user = "ywh";               // 用户
const std::string passwd = "YwhHkty.070407";  // 密码
const std::string db = "conn";                // 使用的库
const unsigned int port = 3306;               // 端口号


int main()
{
    // 初始化
    MYSQL* my = mysql_init(nullptr);
    if(my == nullptr)
    {
        perror("err: \n");
        //std::cerr << "init MySQL error" << std:: endl;
        return 1;
    }

    // 链接数据库
    if(mysql_real_connect(my,host.c_str(),user.c_str(),passwd.c_str(),db.c_str(),port,nullptr,0) == nullptr)
    {
        perror("err: \n");
        std::cerr << "connect MySQL error" << std:: endl;
        return 2;
    }
    std::cout << "connect success" << std::endl;

    // 执行命令
    // const std::string sql = "insert into user values(1, '张三', 18, '1234567')";
    const std::string sql = "select * from user";
    int n = mysql_query(my, sql.c_str());
    if(n != 0)
    {
        std::cerr << "query error" << std::endl;
        return 3;
    }
    
    // 获取查询结果
    MYSQL_RES* res = mysql_store_result(my);
    if(res == nullptr)
    {
        std::cerr << "mysql_store_result error" << std::endl;
        return 4;
    }
    
    // 获取行数
    my_ulonglong rows = mysql_num_rows(res);
    // 获取列数
    my_ulonglong fields = mysql_num_fields(res);
    std::cout << "行:" << rows << std::endl;
    std::cout << "列:" << fields << std::endl;
    
    // 提取结果
    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] << "\t"; // 每一行的每一列
        }
        std::cout << "\n";
    }
    mysql_close(my);
    return 0; 
}

2.5.3 获取列名

MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);