• MySQL使用C语言连接


    一、环境问题

    首先介绍几个我自己的配置环境的时候遇到的问题:
    1.如果你使用的是yum来进行下载的MySQL,那么库文件应该是被配置好了的,如果没有找到,那么需要在官网上进行自己下载。
    2.下载之后连接某一个用户的话,MySQL8.0需要修改密码的加密规则才能成功连接,可以使用函数mysql_error()来进行寻错。
    3.在插入数据的时候出现乱码信息,需要使用mysql_set_charset_set()函数来设置对应的编码规则。

    二、Makefile文件

    编写makefile文件需要一些动静态库的知识,这些在我之前的博客中都有提及(动静态库的链接),这里不多赘述:

    mytest:test.cc
    	g++ -o $@ $^ -std=c++11 -I./include -L./lib -lmysqlclient
    .PHONY:clean
    	rm -rf mytest	
    
    • 1
    • 2
    • 3
    • 4

    三、链接MySQL

    1.准备工作

    首先我们需要明确链接哪一个数据库,用户是谁,用什么主机,端口号是什么等等的信息,这些信息使用字符串来进行保存。

        string user="test";
        string host="127.0.0.1";
        string password = "Homelander@2022";
        string db="db";
        unsigned int port=3306;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.初始化一个句柄

    我们将通过这个句柄来实现和远程数据库的链接或者关闭:

     MYSQL* my=mysql_init(nullptr);//创建并初始化一个MySQL句柄
     mysql_close(my);//关闭mysql句柄
    
    • 1
    • 2

    3.连接数据库

    使用函数mysql_real_connect来链接数据库

        if(mysql_real_connect(my,host.c_str(),user.c_str(),password.c_str(),db.c_str(),port,nullptr,0)==nullptr)
        {
            cout<<mysql_error(my)<<endl;
            cout<<"connect failed"<<endl;
            return 1;
        }
        cout<<"connect succeed"<<endl;
        mysql_set_character_set(my,"utf8");//将编码格式修改为utf8
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    当他的返回值为空的时候,表示没有链接成功,如果你是MySQL8.0,很有可能是因为密码的加密方式导致链接失败。

    4.增删改

    相对于查来说,增删改的操作就比较容易一些,它们的本质是将MySQL的语句当做一个字符串来传入,执行交给mysql_query这个函数来完成:

        string sql="insert into test values(3,\'祖国人\')";
        int res=mysql_query(my,sql.c_str());
        if(res!=0)
        {
            cout<<"execute:"<<sql<<"failed"<<endl;
            return 2;
        }
        cout<<"execute:"<<sql<<endl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    对于sql来说,我们也可以对其执行其他的增删改操作,只需要修改sql的内容就可以了。在MySQL端可以看到已经成功插入了:
    在这里插入图片描述
    注意,在C语言中写MySQL语句的时候需要使用转义字符\,并且最后不需要加分号。

    5.查

    查与增删改不同,查是需要看到内容的,因此需要更多的接口:

    (1)获取句柄中最后一次返回

        string sql="select * from account";
        int res = mysql_query(my, sql.c_str());
        if(res!=0)
        {
            cout<<"execute:"<<sql<<"failed"<<endl;
            return 2;
        }
        MYSQL_RES* result=mysql_store_result(my);//存放mysql句柄中最后一次返回
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    但获取之后,我们就不需要和句柄打交道了,而是直接和返回的result打交道。

    (2)获取行和列

    注意这里的行和列是不包括字段名那一行的。

        int rows=mysql_num_rows(result);
        int cols=mysql_num_fields(result);
        cout<<"行数"<<rows<<"列数"<<cols<<endl;
    
    • 1
    • 2
    • 3

    可以看到不需要再传入句柄了,因为整个select的信息已经被保存在了result中。
    在这里插入图片描述

    (3)获取列名

    使用MYSQL_FIELD结构体类型来获取列名,该结构体的name存放的就是列名。fields是一个指向首列元素的指针。

        MYSQL_FIELD * fields=mysql_fetch_fields(result);
        for(int i=0;i<cols;i++)
        {
            cout<<fields[i].name<<"\t";
        }
        cout<<endl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    (4)获取每行内容

    行处理规则和列处理规则有所不同。
    MYSQL_ROW使用的不是指针类型,fetch的是row而不是rows,需要注意一下这些细节:

        for(int i=0;i<rows;i++)
        {
            MYSQL_ROW line=mysql_fetch_row(result);
            for(int j=0;j<cols;j++)
            {
                cout<<line[j]<<"\t";
            }
            cout<<endl;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    先找到每一行,然后再在行中找到每一列的内容。
    在这里插入图片描述
    此时就获取成功了。

    四、完整代码

    #include
    #include
    #include
    using namespace std;
    int main()
    {
        //printf("mysql client version:%s\n",mysql_get_client_info());
        string user="test";
        string host="127.0.0.1";
        string password = "Homelander@2022";
        string db="db";
        unsigned int port=3306;
        MYSQL* my=mysql_init(nullptr);//创建并初始化一个MySQL句柄
        if(mysql_real_connect(my,host.c_str(),user.c_str(),password.c_str(),db.c_str(),port,nullptr,0)==nullptr)
        {
            cout<<mysql_error(my)<<endl;
            cout<<"connect failed"<<endl;
            return 1;
        }
        cout<<"connect succeed"<<endl;
        mysql_set_character_set(my,"utf8");
        // string sql="insert into test values(3,\'祖国人\')";
        // int res=mysql_query(my,sql.c_str());
        // if(res!=0)
        // {
        //     cout<<"execute:"<
        //     return 2;
        // }
        string sql="select * from account";
        int res = mysql_query(my, sql.c_str());
        if(res!=0)
        {
            cout<<"execute:"<<sql<<"failed"<<endl;
            return 2;
        }
        cout << "execute:" << sql << endl;
        MYSQL_RES* result=mysql_store_result(my);//存放mysql句柄中最后一次返回
        int rows=mysql_num_rows(result);
        int cols=mysql_num_fields(result);
        cout<<"行数"<<rows<<"列数"<<cols<<endl;
        MYSQL_FIELD * fields=mysql_fetch_fields(result);
        for(int i=0;i<cols;i++)
        {
            cout<<fields[i].name<<"\t";
        }
        cout<<endl;
        for(int i=0;i<rows;i++)
        {
            MYSQL_ROW line=mysql_fetch_row(result);
            for(int j=0;j<cols;j++)
            {
                cout<<line[j]<<"\t";
            }
            cout<<endl;
        }
        mysql_close(my);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
  • 相关阅读:
    CSP初赛知识精讲--容斥原理
    区间DP及其拓展
    SAP FI/SD的集成-VKOA科目确定
    ABAP 报表中如何给报表的输入参数增添 F4 Value Help
    助贷系统设计
    分类预测 | MATLAB实现KOA-CNN-BiLSTM开普勒算法优化卷积双向长短期记忆神经网络数据分类预测
    nvm下载node指定版本后npm不存在
    美国服务器速度变慢了有没有解决办法?
    怎么把cad转换成pdf格式?
    vue全局使用sass变量
  • 原文地址:https://blog.csdn.net/qq_51492202/article/details/127332279