【MySQL】使用C/C++来连接 MySQL

一、使用 C/C++ 来连接 MySQL

一般我们安装好 MySQL 之后下面这些头文件都是有的;

查看 MySQL 的头文件:

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

int main()
{
    std::cout << "数据库的版本:" << mysql_get_client_info() << std::endl;
    return 0;
}

连接 MySQL:

cpp 复制代码
MYSQL *mysql_real_connect(
    MYSQL *mysql,           // 连接对象
    const char *host,       // 主机:localhost / 127.0.0.1
    const char *user,       // 用户名:root
    const char *passwd,     // 密码
    const char *db,         // 要连接的数据库名
    unsigned int port,      // 端口:3306
    const char *unix_socket,// 一般填 NULL
    unsigned long clientflag// 一般填 0
);

成功:返回一个非空的连接指针 失败:返回 NULL;

连接数据库:

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

const std::string host = "127.0.0.1";
const std::string user = "lisi";
const std::string password = "123456";
const std::string db = "rootDB";
const unsigned int port = 8080;

int main()
{
    // std::cout << "数据库的版本:" << mysql_get_client_info() << std::endl;

    MYSQL* my = mysql_init(nullptr);// 初始化对象
    if(!my)
    {
        std::cerr << "初始化失败" << std::endl;
        return 1;
    }

    if(mysql_real_connect(my,host.c_str(),user.c_str(),password.c_str(),db.c_str(),port,nullptr,0) == nullptr)
    {
        std::cerr << "连接失败" << std::endl;
        return 2;
    }

    std::cout << "连接成功" << std::endl;

    mysql_close(my);//释放句柄
    return 0;
}

查看是否连接成功:

对 MySQL 下达命令:

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

const std::string host = "127.0.0.1";
const std::string user = "lisi";
const std::string password = "123456";
const std::string db = "rootDB";
const unsigned int port = 8080;

int main()
{
    // std::cout << "数据库的版本:" << mysql_get_client_info() << std::endl;

    MYSQL* my = mysql_init(nullptr);// 初始化对象
    if(!my)
    {
        std::cerr << "初始化失败" << std::endl;
        return 1;
    }

    if(mysql_real_connect(my,host.c_str(),user.c_str(),password.c_str(),db.c_str(),port,nullptr,0) == nullptr)
    {
        std::cerr << "连接失败" << std::endl;
        return 2;
    }

    // sleep(10);
    std::cout << "连接成功" << std::endl;

    std::string sql;
    while(true)
    {
        std::cout << "MYSQL>>> ";
        if(!std::getline(std::cin,sql) || sql == "quit;") break;
        int n = mysql_query(my,sql.c_str());//对 MySQL 下达指令

        if(n == 0) std::cout << sql << "success " << n << std::endl;
        else std::cerr << sql << " failed" << n << std::endl;
    }
    mysql_close(my);//释放句柄
    return 0;
}

一般这么写:

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

const std::string host = "127.0.0.1";
const std::string user = "lisi";
const std::string password = "123456";
const std::string db = "rootDB";
const unsigned int port = 8080;

int main()
{
    // std::cout << "数据库的版本:" << mysql_get_client_info() << std::endl;

    MYSQL* my = mysql_init(nullptr);// 初始化对象
    if(!my)
    {
        std::cerr << "初始化失败" << std::endl;
        return 1;
    }

    if(mysql_real_connect(my,host.c_str(),user.c_str(),password.c_str(),db.c_str(),port,nullptr,0) == nullptr)
    {
        std::cerr << "连接失败" << std::endl;
        return 2;
    }

    // sleep(10);
    std::cout << "连接成功" << std::endl;

    std::string sql = "update t2 set name='Jimy' where id=1";
    int n = mysql_query(my,sql.c_str());
    if(!n) std::cout << sql << " sucess" << std::endl;
    else std::cerr << sql << " failed" << std::endl;

    // while(true)
    // {
    //     std::cout << "MYSQL>>> ";
    //     if(!std::getline(std::cin,sql) || sql == "quit;") break;
    //     int n = mysql_query(my,sql.c_str());//对 MySQL 下达指令

    //     if(n == 0) std::cout << sql << "success " << n << std::endl;
    //     else std::cerr << sql << " failed" << n << std::endl;
    // }
    mysql_close(my);//释放句柄
    return 0;
}

如果编码的客户端(默认是latin1)和服务端的编码方式的不一样,则设置编码方式:

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

const std::string host = "127.0.0.1";
const std::string user = "lisi";
const std::string password = "123456";
const std::string db = "rootDB";
const unsigned int port = 8080;

int main()
{
    // std::cout << "数据库的版本:" << mysql_get_client_info() << std::endl;

    MYSQL* my = mysql_init(nullptr);// 初始化对象
    if(!my)
    {
        std::cerr << "初始化失败" << std::endl;
        return 1;
    }

    if(mysql_real_connect(my,host.c_str(),user.c_str(),password.c_str(),db.c_str(),port,nullptr,0) == nullptr)
    {
        std::cerr << "连接失败" << std::endl;
        return 2;
    }

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

    // sleep(10);
    std::cout << "连接成功" << std::endl;

    std::string sql = "insert into t2 (name) values ('李四')";
    int n = mysql_query(my,sql.c_str());
    if(!n) std::cout << sql << " sucess" << std::endl;
    else std::cerr << sql << " failed" << std::endl;

    // while(true)
    // {
    //     std::cout << "MYSQL>>> ";
    //     if(!std::getline(std::cin,sql) || sql == "quit;") break;
    //     int n = mysql_query(my,sql.c_str());//对 MySQL 下达指令

    //     if(n == 0) std::cout << sql << "success " << n << std::endl;
    //     else std::cerr << sql << " failed" << n << std::endl;
    // }
    mysql_close(my);//释放句柄
    return 0;
}

上面的操作中,对数据库的增删改都可以,都是查 select 的结果我们是需要讨论一下的,当我们 slect 的时候,查找的数据实际上会放到 MySQL* my 的 MySQL结构体的缓冲区中的,为了这个结构体的里面缓冲区的内容读出来,我们使用:MySQL_RES* res = mysql_store_result(my);

在MySQL中将所有的数据读取出来的时候全部当作字符串来处理;实际上 MySQL_RES 读取数据的时候就像上面图片一样,MySQL_RES 里面有个指针数组,里面存储的是另外一个数组的起始地址,那么另外一个数组存储的是MySQL结构体中缓冲区的数据(字符串)的地址;

注意:存储到 res 的除了表的内容还有列名:

为了方便读取 res,我们要指定 res 里面的数据有多少行和列,进而方便我们操作:

获取行:my_ulonglong mysql_num_rows(MYSQL_RES*)

获取列:my_ulonglong mysql_num_fields(MYSQL_RES*)

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

const std::string host = "127.0.0.1";
const std::string user = "lisi";
const std::string password = "123456";
const std::string db = "rootDB";
const unsigned int port = 8080;

int main()
{
    // std::cout << "数据库的版本:" << mysql_get_client_info() << std::endl;

    MYSQL* my = mysql_init(nullptr);// 初始化对象
    if(!my)
    {
        std::cerr << "初始化失败" << std::endl;
        return 1;
    }

    if(mysql_real_connect(my,host.c_str(),user.c_str(),password.c_str(),db.c_str(),port,nullptr,0) == nullptr)
    {
        std::cerr << "连接失败" << std::endl;
        return 2;
    }

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

    // sleep(10);
    std::cout << "连接成功" << std::endl;

    std::string sql = "select * from t2";
    int n = mysql_query(my,sql.c_str());//下达指令
    if(!n) std::cout << sql << " sucess" << std::endl;
    else std::cerr << sql << " failed" << std::endl;

    MYSQL_RES* res = mysql_store_result(my);//获取 MYSQL 结构体的里面缓冲区的数据
    if(!res)
    {
        //res = NULL
        std::cout << "获取失败" << std::endl;
        return 3;
    }

    my_ulonglong rows = mysql_num_rows(res);//获取行
    my_ulonglong fields = mysql_num_fields(res);//获取列

    std::cout << "行:" << rows << std::endl;
    std::cout << "列:" << fields << std::endl;
    

    // while(true)
    // {
    //     std::cout << "MYSQL>>> ";
    //     if(!std::getline(std::cin,sql) || sql == "quit;") break;
    //     int n = mysql_query(my,sql.c_str());//对 MySQL 下达指令

    //     if(n == 0) std::cout << sql << "success " << n << std::endl;
    //     else std::cerr << sql << " failed" << n << std::endl;
    // }
    mysql_close(my);//释放句柄
    return 0;
}

获取某行(不包含属性)的数据的起始地址:

cpp 复制代码
MYSQL_ROW row = mysql_fetch_row(res);
cpp 复制代码
#include <iostream>
#include <mysql/mysql.h>
#include <unistd.h>
#include <string>

const std::string host = "127.0.0.1";
const std::string user = "lisi";
const std::string password = "123456";
const std::string db = "rootDB";
const unsigned int port = 8080;

int main()
{
    // std::cout << "数据库的版本:" << mysql_get_client_info() << std::endl;

    MYSQL *my = mysql_init(nullptr); // 初始化对象
    if (!my)
    {
        std::cerr << "初始化失败" << std::endl;
        return 1;
    }

    if (mysql_real_connect(my, host.c_str(), user.c_str(), password.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
        std::cerr << "连接失败" << std::endl;
        return 2;
    }

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

    // sleep(10);
    std::cout << "连接成功" << std::endl;

    std::string sql = "select * from t2";
    int n = mysql_query(my, sql.c_str()); // 下达指令
    if (!n)
        std::cout << sql << " sucess" << std::endl;
    else
        std::cerr << sql << " failed" << std::endl;

    MYSQL_RES *res = mysql_store_result(my); // 获取 MYSQL 结构体的里面缓冲区的数据, res 结果集
    if (!res)
    {
        // res = NULL
        std::cout << "获取失败" << std::endl;
        return 3;
    }

    // my_ulonglong rows = mysql_num_rows(res);//获取行,注意:my_ulonglong 是 long long 类型
    // my_ulonglong fields = mysql_num_fields(res);//获取列
    // 便于操作 
    int rows = mysql_num_rows(res);     // 获取行
    int 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);// 读取一行的起始地址(数据), MYSQL_RPW 是 char**
        for(int j = 0; j < fields; j++)
        {
            std::cout << row[j] << "\t";//读取一行中每列的数据(char*)
        }
        std::cout << std::endl;
    }

    // while(true)
    // {
    //     std::cout << "MYSQL>>> ";
    //     if(!std::getline(std::cin,sql) || sql == "quit;") break;
    //     int n = mysql_query(my,sql.c_str());//对 MySQL 下达指令

    //     if(n == 0) std::cout << sql << "success " << n << std::endl;
    //     else std::cerr << sql << " failed" << n << std::endl;
    // }
    mysql_close(my); // 释放句柄
    return 0;
}

从上面的结果上看,我们只获取了表内的内容,没有列名,所以:

获取列名:

cpp 复制代码
   //获取结果集里面的所有列的属性
    MYSQL_FIELD* fields_array = mysql_fetch_field(res);

MySQL_FILED 结构体:

显而易见的 MYSQL_RES 结构体定然开辟了许多的空间,跟我上面画的图一样,所以当我们不使用结果集的时候,要释放掉他,不然就会造成内存泄漏:

mysql_free_result(res);

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

const std::string host = "127.0.0.1";
const std::string user = "lisi";
const std::string password = "123456";
const std::string db = "rootDB";
const unsigned int port = 8080;

int main()
{
    // std::cout << "数据库的版本:" << mysql_get_client_info() << std::endl;

    MYSQL *my = mysql_init(nullptr); // 初始化对象
    if (!my)
    {
        std::cerr << "初始化失败" << std::endl;
        return 1;
    }

    if (mysql_real_connect(my, host.c_str(), user.c_str(), password.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
        std::cerr << "连接失败" << std::endl;
        return 2;
    }

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

    // sleep(10);
    std::cout << "连接成功" << std::endl;

    std::string sql = "select * from t2";
    int n = mysql_query(my, sql.c_str()); // 下达指令
    if (!n)
        std::cout << sql << " sucess" << std::endl;
    else
        std::cerr << sql << " failed" << std::endl;

    MYSQL_RES *res = mysql_store_result(my); // 获取 MYSQL 结构体的里面缓冲区的数据, res 结果集
    if (!res)
    {
        // res = NULL
        std::cout << "获取失败" << std::endl;
        return 3;
    }

    // my_ulonglong rows = mysql_num_rows(res);//获取行,注意:my_ulonglong 是 long long 类型
    // my_ulonglong fields = mysql_num_fields(res);//获取列
    // 便于操作 
    int rows = mysql_num_rows(res);     // 获取行
    int fields = mysql_num_fields(res); // 获取列

    std::cout << "行:" << rows << std::endl;
    std::cout << "列:" << fields << std::endl;

    //获取结果集里面的所有列的属性
    MYSQL_FIELD* fields_array = mysql_fetch_field(res);
    for(int i = 0; i < fields; i++)
    {
        std::cout << fields_array[i].name << "\t";
    }
    std::cout << "\n";

    for(int i = 0; i < rows; i++)//读取表的内容
    {
        MYSQL_ROW row = mysql_fetch_row(res);// 读取一行的起始地址(数据), MYSQL_RPW 是 char**
        for(int j = 0; j < fields; j++)
        {
            std::cout << row[j] << "\t";//读取一行中每列的数据(char*)
        }
        std::cout << std::endl;
    }

    // while(true)
    // {
    //     std::cout << "MYSQL>>> ";
    //     if(!std::getline(std::cin,sql) || sql == "quit;") break;
    //     int n = mysql_query(my,sql.c_str());//对 MySQL 下达指令

    //     if(n == 0) std::cout << sql << "success " << n << std::endl;
    //     else std::cerr << sql << " failed" << n << std::endl;
    // }
    mysql_free_result(res);
    mysql_close(my); // 释放句柄
    return 0;
}

二、使用图形化界面来连接 MySQL

执行命令:选中和点击闪电

可直接在图形化的表进行修改,然后进行 apply:

相关推荐
入瘾1 天前
etcd 显示连接失败
数据库·chrome·etcd
本体智能1 天前
预制指标、宽表、SQL、本体ABC:真正决定长期成本的,是一次变更会波及多少层
数据库·sql·本体神经网络·uino数据智能引擎
长安11081 天前
数据库基础知识----数据库大观
数据库·oracle
J超会运1 天前
OpenEuler系统MySQL故障排查终极指南
mysql
瀚高PG实验室1 天前
使用hgdbdeveloper开发工具导出数据后在异机恢复时报错
数据库·瀚高数据库
百结2141 天前
PostgreSQL 初体验
数据库·postgresql
ward RINL1 天前
Redis 安装及配置教程(Windows)【安装】
数据库·windows·redis
bingHHB1 天前
金蝶云星空旗舰版 × 赛狐ERP:亚马逊卖家业财一体化的最后一公里
运维·数据库·集成学习
Nontee1 天前
Redis高可用架构解析
数据库·redis·架构
淼淼爱喝水1 天前
DVWA SQL 注入(Medium/High 级别)过滤绕过与防范实验(超详细图文版)
数据库·sql·网络安全