【MySQL】使用C语言连接

👉mysql connect👈

连接库的下载

学习 MySQL 的命令行,只是让我们熟悉 MySQL 的命令。在实际工作和项目开发中,我们都是使用封装好的库来连接和访问 MySQL 数据库的。

要使用 C 语言连接 MySQL,需要使用 MySQL官网提供的库,大家可以去官网下载。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下载完之后,上传到 Linux 服务器上,然后解压就行了。

[root@VM-12-10-centos mysql-connector]# ll
total 68
drwxrwxr-x 2 Joy Joy  4096 Jul 24 13:54 bin
-rw-r--r-- 1 Joy Joy 17987 Jul 13  2017 COPYING
drwxrwxr-x 2 Joy Joy  4096 Jul 24 13:54 docs
drwxrwxr-x 3 Joy Joy  4096 Jul 24 13:54 include
drwxrwxr-x 2 Joy Joy  4096 Jul 24 13:54 lib
-rw-r--r-- 1 Joy Joy 30906 Jul 13  2017 README

[root@VM-12-10-centos mysql-connector]# ll lib/
total 23916
-rw-r--r-- 1 Joy Joy 15948896 Jul 13  2017 libmysqlclient.a
lrwxrwxrwx 1 Joy Joy       20 Jul 13  2017 libmysqlclient.so -> libmysqlclient.so.18
lrwxrwxrwx 1 Joy Joy       23 Jul 13  2017 libmysqlclient.so.18 -> libmysqlclient.so.18.4.
-rwxr-xr-x 1 Joy Joy  8538815 Jul 13  2017 libmysqlclient.so.18.4.

其中 include 目录下包含了所有的方法声明, lib 目录下包含所有的方法实现(打包成库)。然后再将头文件和库文件拷贝到系统目录下就完成安装了。

但是,我们在安装 MySQL 服务时,就已经把 MySQL 的开发包安装好了,也会自动地将头文件和库文件拷贝到系统目录下。

[root@VM-12-10-centos mysql-connector]# rpm -qa | grep mysql
mysql57-community-release-el7-11.noarch
mysql-community-client-5.7.41-1.el7.x86_64
mysql-community-libs-5.7.41-1.el7.x86_64
mysql-community-common-5.7.41-1.el7.x86_64
mysql-community-server-5.7.41-1.el7.x86_64
mysql-community-devel-5.7.43-1.el7.x86_6 ## 开发包

## 如果发现自己没有开发包,可以使用下面的命令进行下载
yum install -y mysql-community-devel

## 查看系统目录下的头文件和库文件
[root@VM-12-10-centos mysql-connector]# ls /usr/include/mysql/
big_endian.h              my_byteorder.h      mysql_com.h         my_sys.h                    sql_state.h
binary_log_types.h        my_command.h        mysql_com_server.h  my_thread.h                 sslopt-case.h
byte_order_generic.h      my_compiler.h       mysqld_ername.h     my_thread_local.h           sslopt-longopts.h
byte_order_generic_x86.h  my_config.h         mysqld_error.h      my_xml.h                    sslopt-vars.h
decimal.h                 my_config_x86_64.h  mysql_embed.h       plugin_audit.h              thr_cond.h
errmsg.h                  my_dbug.h           mysql.h             plugin_ftparser.h           thr_mutex.h
keycache.h                my_dir.h            mysql_time.h        plugin_group_replication.h  thr_rwlock.h
little_endian.h           my_getopt.h         mysql_version.h     plugin.h                    typelib.h
m_ctype.h                 my_global.h         mysqlx_ername.h     plugin_keyring.h
m_string.h                my_list.h           mysqlx_error.h      plugin_validate_password.h
my_alloc.h                mysql               mysqlx_version.h    sql_common.h

[root@VM-12-10-centos mysql-connector]# ls /usr/lib64/mysql/
libmysqlclient.a   libmysqlclient.so.20       libmysqlservices.a  plugin
libmysqlclient.so  libmysqlclient.so.20.3.28  mecab

验证是否引入成功

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

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

using namespace std;

int main()
{
    cout << "MySQL Client Version:" << mysql_get_client_info() << endl;
    return 0;
}

因为我们的连接库所在的路径没有导入到系统的环境变量中,所以我们要通过 -L 选项和 -l 选项来告知编译器库文件所在的路径和所要链接的库。

Makefile

# -L:指明库文件的所在路径
# -l:指明所要链接的库
mysqlClient:mysqlClient.cc
	g++ $@ $^ -o -std=c++11 -L/lib64/mysql -lmysqlclient

.PHONY:clean
clean:
	rm -rf mysqlClient

在这里插入图片描述

mysql 接口介绍

初始化 mysql_init

要使用库,必须先进行初始化。mysql_init 函数会给我们返回一个 MYSQL 句柄,我们后续的操作都需要通过这个 MYSQL 句柄来完成。使用方法如下:

MYSQL *m= mysql_init(nullptr);

连接数据库 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);
						  
// 建立好链接之后,获取英文没有问题,如果获取中文是乱码:
// 设置链接的默认字符集是utf8,原始默认是latin1
mysql_set_character_set(myfd, "utf8");

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

关闭 mysql 连接 mysql_close

void mysql_close(MYSQL *sock);

使用完数据库后,需要关闭 mysql 连接,否则会造成内存泄露。

下发 mysql 命令 mysql_query

int mysql_query(MYSQL *mysql, const char *q);

第一个参数上面已经介绍过,第二个参数为要执行的 sql 语句,如:“select * from table”。调用成功的返回值为 0,否则为 1。

获取执行结果 mysql_store_result

sql 执行完以后,如果是查询语句,我们当然还要读取数据。如果 update、insert 等语句,那么就看下操作成功与否即可。那我们来看看如何获取查询结果,如果 mysql_query 返回成功,那么我们就通过 mysql_store_result 这个函数来读取结果。原型如下:

MYSQL_RES *mysql_store_result(MYSQL *mysql);

该函数会调用 MYSQL 变量中的 st_mysql_methods 中的 read_rows 函数指针来获取查询的结果。同时该函数会返回 MYSQL_RES 这样一个变量,该变量主要用于保存查询的结果。同时该函数 malloc 了一片内存空间来存储查询过来的数据,所以我们一定要记的 free(result),不然是肯定会造成内存泄漏的。 执行完 mysql_store_result 以后,其实数据都已经在 MYSQL_RES 变量中了,下面的 API 基本就是读取 MYSQL_RES 中的数据。

获取结果行数 mysql_num_rows

my_ulonglong mysql_num_rows(MYSQL_RES *res);

获取结果列数 mysql_num_fields

unsigned int mysql_num_fields(MYSQL_RES *res);

获取列名 mysql_fetch_fields

MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);

如:

int fields = mysql_num_fields(res);
MYSQL_FIELD *field = mysql_fetch_fields(res);
int i = 0;
for (; i < fields; i++)
{
    cout << field[i].name << " ";
}
cout << endl;

获取结果内容 mysql_fetch_row

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);

它会返回一个 MYSQL_ROW 变量,MYSQL_ROW 其实就是 char **,可以当成一个二维数组来使用。

MYSQL_ROW line;
for (int i = 0; i < rows; i++)
{
    line = mysql_fetch_row(res);
    for (int j = 0; j < fields; j++)
    {
        cout << line[j] << " ";
    }
    cout << endl;
}

另外,mysql C API 还支持事务等常用操作,大家自行了解。

综合代码

获取 select 的结果

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

using namespace std;

string User = "Test";
string Host = "127.0.0.1"; // "localhost"
string Password = "123456";
string Database = "my_db";
unsigned int Port = 8888;

int main()
{
    // 初始化 MYSQL 对象
    MYSQL *m = mysql_init(nullptr);
    if (m == nullptr)
    {
        cerr << "mysql_init error" << endl;
        exit(1);
    }

    // 连接数据库
    if (mysql_real_connect(m, Host.c_str(), User.c_str(), Password.c_str(), Database.c_str(), Port, nullptr, 0) == nullptr)
    {
        cerr << "mysql_real_connect error" << endl;
        exit(2);
    }

    // 将 mysql 连接的字符集设置为 utf8
    // 如果没有设置, 有中文将会出现乱码
    mysql_set_character_set(m, "utf8");

    cout << "mysql_real_connect success" << endl;

    // SQL 可以从网络中来,那样就可以将用户的数据存储起来
    // 增删改的 SQL 语句:执行完就可以了
    // 而查的 SQL 语句:执行完还有读取结果
    string insertSql = "insert into emp values (2, '张三', 8888)";
    string deleteSql = "delete from emp where id=2";
    string updateSql = "update emp set sal=9999 where name='张三'";
    string selectSql = "select * from emp";

    int n = mysql_query(m, selectSql.c_str());
    // 查看执行结果: 0 表示执行成功, 1 表示执行失败
    if (n == 0)
    {
        // 获取结果并对结果进行解析
        MYSQL_RES* res = mysql_store_result(m);
        if(res == nullptr) exit(3);
        int rows = mysql_num_rows(res);
        int fields = mysql_num_fields(res);

        MYSQL_FIELD* fieldName = mysql_fetch_fields(res);
        for(int j = 0; j < fields; ++j)
        {
            // 格式控制
            cout << std::setw(10) << std::left;
            cout << fieldName[j].name;
        }
        cout << endl;

        MYSQL_ROW line;
        for(int i = 0; i < rows; ++i)
        {
            // 按行获取结果内容, 获取完会自动移动到下一行
            line = mysql_fetch_row(res);
            for(int j = 0; j < fields; ++j)
            {
                cout << std::setw(10) << std::left;
                cout << line[j];
            }
            cout << endl;
        }

        // 释放内存
        mysql_free_result(res);
    }

    // 关闭 mysql 连接
    mysql_close(m);

    return 0;
}

简易版 mysql 客户端的实现

#include <iostream>
#include <string>
#include <cstring>
#include <iomanip>
#include <cstdlib>
#include <mysql/mysql.h>

using namespace std;

string User = "Test";
string Host = "127.0.0.1"; // "localhost"
string Password = "123456";
string Database = "my_db";
unsigned int Port = 8888;

int main()
{
    // 初始化 MYSQL 对象
    MYSQL *m = mysql_init(nullptr);
    if (m == nullptr)
    {
        cerr << "mysql_init error" << endl;
        exit(1);
    }

    // 连接数据库
    if (mysql_real_connect(m, Host.c_str(), User.c_str(), Password.c_str(), Database.c_str(), Port, nullptr, 0) == nullptr)
    {
        cerr << "mysql_real_connect error" << endl;
        exit(2);
    }

    // 将 mysql 连接的字符集设置为 utf8
    // 如果没有设置, 有中文将会出现乱码
    mysql_set_character_set(m, "utf8");
    cout << "mysql_real_connect success" << endl << endl;

    char sql[1024];
    while (true)
    {
        cout << "mysql> ";
        fgets(sql, sizeof sql, stdin);
        sql[strlen(sql) - 1] = '\0'; // 去掉 '\n'

        int n = mysql_query(m, sql);
        // 查看执行结果: 0 表示执行成功, 1 表示执行失败
        if (n == 0)
        {
            if (strcasestr(sql, "select"))
            {
                // 获取结果并对结果进行解析
                MYSQL_RES *res = mysql_store_result(m);
                if (res == nullptr)
                    exit(3);
                int rows = mysql_num_rows(res);
                int fields = mysql_num_fields(res);

                MYSQL_FIELD *fieldName = mysql_fetch_fields(res);
                for (int j = 0; j < fields; ++j)
                {
                    // 格式控制
                    cout << std::setw(10) << std::left;
                    cout << fieldName[j].name;
                }
                cout << endl;

                MYSQL_ROW line;
                for (int i = 0; i < rows; ++i)
                {
                    // 按行获取结果内容, 获取完会自动移动到下一行
                    line = mysql_fetch_row(res);
                    for (int j = 0; j < fields; ++j)
                    {
                        cout << std::setw(10) << std::left;
                        cout << line[j];
                    }
                    cout << endl;
                }
                cout << endl;
                // 释放内存
                mysql_free_result(res);
            }
            else
            {
                printf("execute %s success\n\n", sql);
            }
        }
        else
        {
            printf("execute %s fail\n\n", sql);
        }
    }

    // 关闭 mysql 连接
    mysql_close(m);

    return 0;
}

在这里插入图片描述

👉总结👈

本篇博客主要讲解了 mysql 连接库的下载和安装、mysql 接口介绍以及实现了简易版的 mysql 客户端等等。以上就是本篇博客的全部内容,如果大家觉得有收获的话,可以点个三连支持一下!谢谢大家啦!💖💝❣️

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值