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

mysql connect

mysql的基础,我们之前已经学过,后面我们只关心使用

要使用C语言连接mysql,需要使用mysql官网提供的库,大家可以去官网下载

我们使用C接口库来进行连接

要正确使用,我们需要做一些准备工作:

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

Connector/C 使用

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

sql 复制代码
[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
sql 复制代码
[root@iZ0jl69kyvg0h181cozuf5Z ~]# ls /usr/include -d
/usr/include
[root@iZ0jl69kyvg0h181cozuf5Z ~]# ls /usr/include/mysql -d
/usr/include/mysql
sql 复制代码
[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进行编写下述代码:

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

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

编译并运行

sql 复制代码
[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

sql 复制代码
[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. 初始化与关闭

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

sql 复制代码
#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的)

sql 复制代码
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函数中各参数,基本都是顾名思意。

sql 复制代码
#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:

sql 复制代码
    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:

sql 复制代码
    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; 

解决乱码问题

客户端和服务器端对于编码问题没有达成一致,导致乱码问题

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

4. 下达SQL指令(显示)

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中不仅包含内容还包含属性

原型如下:

sql 复制代码
MYSQL_RES *mysql_store_result(MYSQL *mysql);

该函数会调用MYSQL变量中的st_mysql_methods中的 read_rows 函数指针来获取查询的结果。同时该函数会返回MYSQL_RES 这样一个变量,该变量主要用于保存查询的结果。

同时该函数malloc了一片内存空间来存储查询过来的数据,所以我们一定要记的 free(result),不然是肯定会造成内存泄漏的。

支持事务

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

sql 复制代码
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);
相关推荐
小兜全糖(xdqt)43 分钟前
mysql数据同步到sql server
mysql·adb
Karoku0661 小时前
【企业级分布式系统】Zabbix监控系统与部署安装
运维·服务器·数据库·redis·mysql·zabbix
~yY…s<#>1 小时前
【刷题17】最小栈、栈的压入弹出、逆波兰表达式
c语言·数据结构·c++·算法·leetcode
周全全1 小时前
MySQL报错解决:The user specified as a definer (‘root‘@‘%‘) does not exist
android·数据库·mysql
白云如幻1 小时前
MySQL的分组函数
数据库·mysql
EricWang13583 小时前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
我是谁??3 小时前
C/C++使用AddressSanitizer检测内存错误
c语言·c++
秋意钟4 小时前
MySQL日期类型选择建议
数据库·mysql
希言JY4 小时前
C字符串 | 字符串处理函数 | 使用 | 原理 | 实现
c语言·开发语言
午言若4 小时前
C语言比较两个字符串是否相同
c语言