自学内容网 自学内容网

【MySQL】20. 使用C语言链接

mysql connect
mysql的基础,我们之前已经学过,后面我们只关心使用
要使用C语言连接mysql,需要使用mysql官网提供的库,大家可以去官网下载
我们使用C接口库来进行连接
要正确使用,我们需要做一些准备工作:

  • 保证mysql服务有效
  • 在官网上下载合适自己平台的mysql connect库,以备后用

Connector/C 使用

我们下下来的库格式如下:

[root@iZ0jl69kyvg0h181cozuf5Z ~]# ls /usr/include/mysql
big_endian.h              my_compiler.h       mysql_embed.h      plugin_group_replication.h
binary_log_types.h        my_config.h         mysql.h            plugin.h
byte_order_generic.h      my_config_x86_64.h  mysql_time.h       plugin_keyring.h
byte_order_generic_x86.h  my_dbug.h           mysql_version.h    plugin_validate_password.h
decimal.h                 my_dir.h            mysqlx_ername.h    sql_common.h
errmsg.h                  my_getopt.h         mysqlx_error.h     sql_state.h
keycache.h                my_global.h         mysqlx_version.h   sslopt-case.h
little_endian.h           my_list.h           my_sys.h           sslopt-longopts.h
m_ctype.h                 mysql               my_thread.h        sslopt-vars.h
m_string.h                mysql_com.h         my_thread_local.h  thr_cond.h
my_alloc.h                mysql_com_server.h  my_xml.h           thr_mutex.h
my_byteorder.h            mysqld_ername.h     plugin_audit.h     thr_rwlock.h
my_command.h              mysqld_error.h      plugin_ftparser.h  typelib.h
[root@iZ0jl69kyvg0h181cozuf5Z ~]# ls /usr/include -d
/usr/include
[root@iZ0jl69kyvg0h181cozuf5Z ~]# ls /usr/include/mysql -d
/usr/include/mysql
[root@iZ0jl69kyvg0h181cozuf5Z ~]# ls /lib64/mysql/*
/lib64/mysql/libmysqlclient.a      /lib64/mysql/libmysqlclient.so.20.3.31
/lib64/mysql/libmysqlclient.so     /lib64/mysql/libmysqlservices.a
/lib64/mysql/libmysqlclient.so.20

/lib64/mysql/mecab:
dic  etc

/lib64/mysql/plugin:
adt_null.so                         keyring_file.so     rewrite_example.so
authentication_ldap_sasl_client.so  keyring_udf.so      rewriter.so
auth_socket.so                      libmemcached.so     semisync_master.so
connection_control.so               libpluginmecab.so   semisync_slave.so
debug                               locking_service.so  validate_password.so
group_replication.so                mypluglib.so        version_token.so
ha_example.so                       mysql_no_login.so
innodb_engine.so                    mysqlx.so

用vscode进行编写下述代码:

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

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

编译并运行

[hx@iZ0jl69kyvg0h181cozuf5Z test_c]$ g++ -o test test.cc -L/lib64/mysql -lmysqlclient
[hx@iZ0jl69kyvg0h181cozuf5Z test_c]$ ll
total 16
-rwxrwxr-x 1 hx hx 9040 Apr  7 13:44 test
-rw-rw-r-- 1 hx hx  157 Apr  7 13:42 test.cc
[hx@iZ0jl69kyvg0h181cozuf5Z test_c]$ ./test
mysql client version :5.7.44

当前MySQL的版本是5.7.44

[hx@iZ0jl69kyvg0h181cozuf5Z test_c]$ ldd test
        linux-vdso.so.1 =>  (0x00007ffff7027000)
        libmysqlclient.so.20 => /usr/lib64/mysql/libmysqlclient.so.20 (0x00007fcf248e3000)
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fcf245db000)
        libm.so.6 => /lib64/libm.so.6 (0x00007fcf242d9000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fcf240c3000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fcf23cf5000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fcf23ad9000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007fcf238d5000)
        librt.so.1 => /lib64/librt.so.1 (0x00007fcf236cd000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fcf25287000)

g++ 编译时后面带的选项(-L / -l) 所代表的意思,请翻阅之前Linux博客当中的软硬链接这块
通过ldd可以看到test和mysqlclient建立了链接

至此引入库的工作已经做完,接下来就是熟悉接口

mysql接口介绍

这些接口的具体使用方案可以在MySQL的官网进行查看
我们采用的是C语言的方式链接,所以我们打开C语言的使用文档即可:

1. 初始化与关闭

要使用库,必须先进行初始化!

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

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

    mysql_close(my);
    return 0;
}

2. 链接数据库

链接数据库mysql_real_connect
初始化完毕之后,必须先链接数据库,在进行后续操作。(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);

第一个参数 MYSQL是 C api中一个非常重要的变量(mysql_init的返回值),里面内存非常丰富,有port,dbname,charset等连接基本参数。它也包含了一个叫 st_mysql_methods的结构体变量,该变量里面保存着很多函数指针,这些函数指针将会在数据库连接成功以后的各种数据操作中被调用。mysql_real_connect函数中各参数,基本都是顾名思意。

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

//const std::string host = "127.0.0.1";
const std::string host = "localhost";
const std::string user = "hx";
const std::string passwd = "123456";
const std::string db = "scott";
const unsigned int port = 3306;

int main()
{
    // std::cout << "mysql client version :" << mysql_get_client_info() << std::endl;
    
    MYSQL *my = mysql_init(nullptr);
    if(nullptr == my)
    {
        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)
    {
        std::cerr << "connect MySQL error" << std::endl;
        return 2;
    }
    std::cout << "connect success" << std::endl;
    mysql_close(my);
    return 0;
}

3. 下达SQL指令(增删改)

方式1:

    std::string sql;
    while(true)
    {
        std::cout << "MySQL>>>";
        // getline 读取一行sql到cin当中
        if(!std::getline(std::cin,sql) || sql == "quit")
        {
            std::cout << "ByeBye~" << std::endl;
            break;
        }
        int n = mysql_query(my,sql.c_str());
        // 如果n == 0 那么就获取到sql中的语句
        if(n == 0)
        {
            std::cout << sql << "success: " << n << std::endl;
        }
        else
        {
            std::cerr << sql << "failed: " << n << std::endl;
        }
    }

在这里插入图片描述

方式2:

    std:: string sql = "update stu set name='HXHX' where id = 1 "; 
    int n = mysql_query(my,sql.c_str());
    if(n == 0) std::cout << sql << "success" << std::endl;
    else std::cout << sql << "failed" << std::endl; 

在这里插入图片描述

解决乱码问题

客户端和服务器端对于编码问题没有达成一致,导致乱码问题
在这里插入图片描述

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

在这里插入图片描述

4. 下达SQL指令(显示)

    std::string sql = "select * from stu";
    int n = mysql_query(my,sql.c_str());
    if(n == 0) std::cout << sql << "success" << std::endl;
    else 
    {   
        std::cout << sql << "failed" << std::endl;
        return 3;
    } 

    MYSQL_RES *res = mysql_store_result(my);
    if(nullptr == res)
    {
        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;

    // 属性
    MYSQL_FIELD *fields_array = mysql_fetch_fields(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);
        for(int j = 0; j < fields; j++)
        {
            std::cout << row[j] << "\t";
        }
        std::cout << "\n";
    }

MYSQL_RES *res中不仅包含内容还包含属性
在这里插入图片描述
在这里插入图片描述
原型如下:

MYSQL_RES *mysql_store_result(MYSQL *mysql);

该函数会调用MYSQL变量中的st_mysql_methods中的 read_rows 函数指针来获取查询的结果。同时该函数会返回MYSQL_RES 这样一个变量,该变量主要用于保存查询的结果。
同时该函数malloc了一片内存空间来存储查询过来的数据,所以我们一定要记的 free(result),不然是肯定会造成内存泄漏的。

支持事务

另外,mysql C api还支持事务等常用操作,大家下来自行了解:

my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode);
my_bool STDCALL mysql_commit(MYSQL * mysql);
my_bool STDCALL mysql_rollback(MYSQL * mysql);

原文地址:https://blog.csdn.net/weixin_60915103/article/details/137234511

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!