当前位置: 首页 > article >正文

【项目组件】第三方库——MySQL CAPI

目录

前言

MySQL CAPI的功能

MySQL CAPI的接口

句柄初始化 

连接MySQL服务器 

设置当前字符集 

选择操作数据库 

执行SQL语句 

保存查询结果到本地(获取结果集)

获取结果集中的行数

获取结果集中的列数 

遍历结果集 

释放结果集

关闭MySQL连接 

获取错误原因 

MySQL CAPI的使用 


前言

注意:本文介绍不会涉及MySQL数据库,已经默认读者掌握了MySQL的增删查改SQL语句的基础上使用MySQL CAPI第三方库


MySQL CAPI的功能

mysql本质是c/s模式, 我们之前使用MySQL时都是通过连接mysqld,然后输入SQL语句的方式实现的数据库的增删查改

在我们实际项目中,不可能再像之前一样,直接连接数据库输入SQL语句,我们需要有一种方法可以让我们编写的代码执行特定的SQL语句!

MySQL CAPI提供了一种用C语言代码操作数据库的功能


MySQL CAPI的接口

MySQL CAPI所包含的头文件默认是:mysql/mysql.h 


句柄初始化 

使用MySQL API的各种操作,我们都需要创建一个操作句柄,MySQL API提供了如下接口初始化操作句柄:

MYSQL *mysql_init(MYSQL *mysql);
  • mysql_init的功能是初始化一个操作句柄
  • mysql_init的参数mysql若传递空的话,mysql_init函数内部在堆上申请一个句柄对象并返回。
  • mysql_init若初始化句柄成功返回句柄指针,否则返回NULL 

连接MySQL服务器 

如下接口:

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 client_flag);
  • mysql:已完成初始化的句柄指针,此为输出型参数。后续所有使用句柄指针的操作,使用该参数变量
  • host:主机号字符串。(MySQL可以支持远程连接,但需要通过特殊配置)
  • user:登录用户字符串。
  • passwd:登录密码字符串
  • db:默认选择的数据库
  • port:端口号,一般为3306
  • unix_socket:通信管道文件或者socket文件,通常置为NULL
  • client_flag:客户端标志位,通常置为0
  • 返回值:若连接成功,返回句柄指针。否则返回NULL 。

设置当前字符集 

如下接口:

int mysql_set_character_set(MYSQL *mysql, const char *csname)
  • mysql:已完成初始化的句柄指针
  • csname:字符集名称,通常是"utf8"
  • 返回值:设置成功返回0,否则返回非0

选择操作数据库 

如下接口:

int mysql_select_db(MYSQL *mysql, const char *db)
  • mysql:已完成初始化的句柄指针
  • db:要选择的数据库名
  • 返回值:选择成功返回0,否则返回非0 

执行SQL语句 

如下接口: 

int mysql_query(MYSQL *mysql, const char *stmt_str)
  • mysql:已完成初始化的句柄指针
  • stmt_str:要执行的SQL语句
  • 返回值:执行成功返回0,否则返回非0 

保存查询结果到本地(获取结果集)

如下接口:

MYSQL_RES *mysql_store_result(MYSQL *mysql)
  • mysql:已完成初始化的句柄指针
  • 返回值:若成功返回MYSQL_RES对象,该对象中保存的是查询结果信息,可以通过后续接口对结果进行操作。若失败返回NULL。(MYSQL_RES*对象我们称为结果集) 

注意:返回的MYSQL_RES*对象是在堆上申请空间的,需要通过后续接口进行手动释放,否则会造成内存泄露


获取结果集中的行数

uint64_t mysql_num_rows(MYSQL_RES *result);
  • 功能:查看result结果集的行数,也就是你通过select * from获取的信息行数/记录个数 

获取结果集中的列数 

unsigned int mysql_num_fields(MYSQL_RES *result)
  • 功能:查看result结果集的列数。 

遍历结果集 

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)
  • 功能:用于遍历result结果集
  • MYSQL_ROW:该类型是一个char**类型,它保存了一行数据记录的信息 

注意:这个接⼝会保存当前读取结果位置,每次获取的都是下⼀条记录 

如何遍历?

  • 先使用该接口获取第一行记录
  • 通过[i]的方式遍历获取第一行第i列数据
  • 再次调用该接口获取第二行记录
  • ...

释放结果集

void mysql_free_result(MYSQL_RES *result)
  • result:待释放结果集 

关闭MySQL连接 

void mysql_close(MYSQL *mysql)
  • 该接口完成了两个动作。释放mysql句柄指针和关闭mysql连接
  • mysql:待释放句柄指针 

获取错误原因 

const char *mysql_error(MYSQL *mysql)
  • 该接口用于获取mysql接口执行错误原因
  • mysql:已初始化的句柄指针
  • 返回值:错误信息

MySQL CAPI的使用 

创建测试数据库和表

 创建数据库的操作需要我们mysql连接数据库后通过SQL语句创建

create database if not exists test_db;
use test_db;
create table stu(
 id int primary key auto_increment, -- 学⽣id 
 age int, -- 学⽣年龄 
 name varchar(32) -- 学⽣姓名 
);

 使用MySQL CAPI完成数据库的增删改操作

要使用MySQL CAPI完成数据库的增删改所有操作,那么我们大致分为六步:

  1. 初始化mysql句柄
  2. 连接服务器
  3. 设置客户端字符集
  4. 选择要操作的数据库
  5. 执行SQL语句
  6. 关闭连接

#include <iostream>
#include <mysql/mysql.h>
#include <string>
#define HOST "127.0.0.1"
#define USER "root"
#define PASSWD ""
#define DB "test_db"
#define PORT 3306
int main()
{
    // 初始化mysql句柄
    MYSQL* mysql = mysql_init(nullptr);
    // 连接服务器
    if(mysql_real_connect(mysql,HOST,USER,PASSWD,DB,PORT,nullptr,0) == nullptr)
    {
        printf("connect mysql server failed: %s\n",mysql_errno(mysql));
        mysql_close(mysql);
        return -1;
    }

    // 设置客户端字符集
    if(mysql_set_character_set(mysql,"utf8") != 0)
    {
        printf("set mysql client character_set error: %s\n",mysql_errno(mysql));
        mysql_close(mysql);
        return -1;
    }

    // 选择要操作的数据库
    //由于我们在连接数据库时的默认选择数据库就是test_db,无需再次选择

    //执行SQL语句
    std::string ins = "insert into stu ";
    if(mysql_query(mysql,(ins + "values(null,18,'张三')").c_str()) != 0)
    {
        printf("ins error: %s\n",mysql_errno(mysql));
        mysql_close(mysql);
        return -1;
    }

    mysql_close(mysql);
    return 0;
}

上述执行SQL语句只展示了增加,对于删除和修改时的步骤都是类似的! 

 注意:编译时由于MySQL CAPI所在的路径不在/usr/include下,它在/usr/lib64/mysql/下。所以我们需要通过-L指定库文件所在路径,同时链接的库名为mysqlclient

g++ -o test Main.cc -std=c++11 -L/usr/lib64/mysql/ -lmysqlclient

 使用MySQL CAPI完成数据库的查找

完成数据库查找时的步骤与增删改时的步骤都差不多,它们之间的区别是在执行SQL语句后的动作!

MySQL CAPI完成数据库查找的步骤:

  • ...
  • 执行SQL查询语句
  • 保存结果到本地结果集中
  • 获取结果集中的结果条数
  • 遍历保存好的结果集
  • 释放结果集
  • 关闭连接 

#include <iostream>
#include <mysql/mysql.h>
#include <string>
#define HOST "127.0.0.1"
#define USER "root"
#define PASSWD ""
#define DB "test_db"
#define PORT 3306
int main()
{
    // 初始化mysql句柄
    MYSQL* mysql = mysql_init(nullptr);
    // 连接服务器
    if(mysql_real_connect(mysql,HOST,USER,PASSWD,DB,PORT,nullptr,0) == nullptr)
    {
        printf("connect mysql server failed: %s\n",mysql_errno(mysql));
        mysql_close(mysql);
        return -1;
    }

    // 设置客户端字符集
    if(mysql_set_character_set(mysql,"utf8") != 0)
    {
        printf("set mysql client character_set error: %s\n",mysql_errno(mysql));
        mysql_close(mysql);
        return -1;
    }

    // 选择要操作的数据库
    //由于我们在连接数据库时的默认选择数据库就是test_db,无需再次选择

    //执行SQL插入语句,插入三条记录
    if(mysql_query(mysql,"insert into stu values(null,18,'张三')") != 0)
    {
        printf("ins error: %s\n",mysql_errno(mysql));
        mysql_close(mysql);
        return -1;
    }
    if(mysql_query(mysql,"insert into stu values(null,19,'李四')") != 0)
    {
        printf("ins error: %s\n",mysql_errno(mysql));
        mysql_close(mysql);
        return -1;
    }
    if(mysql_query(mysql,"insert into stu values(null,20,'王五')") != 0)
    {
        printf("ins error: %s\n",mysql_errno(mysql));
        mysql_close(mysql);
        return -1;
    }
    //之后是查询的步骤
    //执行SQL查询语句
    if(mysql_query(mysql,"select * from stu") != 0)
    {
        printf("sel error: %s\n",mysql_errno(mysql));
        mysql_close(mysql);
        return -1;
    }
    //保存结果到本地结果集中
    MYSQL_RES* res = mysql_store_result(mysql);
    if(res == nullptr)
    {
        mysql_close(mysql);
        return -1;
    }
    //获取结果集的行列数
    int num_row = mysql_num_rows(res);
    int num_col = mysql_num_fields(res);
    //遍历保存好的结果集
    for(int i = 0 ; i < num_row ; ++i)
    {
        MYSQL_ROW row = mysql_fetch_row(res);
        for(int j = 0 ; j < num_col ; ++j)
        {
            std::cout << row[j] << "  ";
        }
        std::cout << std::endl;
    }
    //释放结果集
    mysql_free_result(res);
    //关闭连接
    mysql_close(mysql);
    return 0;
}


http://www.kler.cn/a/401036.html

相关文章:

  • Elasticsearch集群拒绝请求:索引磁盘使用超限
  • 计算机编程中的测试驱动开发(TDD)及其在提高代码质量中的应用
  • ES6进阶知识二
  • 群控系统服务端开发模式-应用开发-前端级别功能开发
  • event_base
  • OpenSSL 自签名
  • 在ubuntu下将virtualbox虚拟机的磁盘重设大小的方法
  • [element-ui]根据 el-table的某一列值大小设置该列背景颜色宽度
  • 细说STM32单片机DMA中断收发RTC实时时间并改善其鲁棒性的方法
  • 《Python网络安全项目实战》项目6 编写密码工具程序_练习题(1)
  • 【大模型UI\多模型回复UI】
  • 【LeetCode】每日一题 2024_11_14 统计好节点的数目(图/树的 DFS)
  • 计算机网络-MSTP工作原理
  • 学习QT第二天
  • RocketMQ 消费队列的写入跟commit log的写入是否同步进行的
  • C++builder中的人工智能(27):如何将 GPT-3 API 集成到 C++ 中
  • 全面掌握Spring Boot异常处理:策略与实践
  • LeetCode77:组合(剪枝操作)
  • prop校验,prop和data区别
  • 数组相关的面试题
  • 基于Java Springboot图书借阅系统
  • 【进阶系列】正则表达式 #匹配
  • 探寻优质的 PostgreSQL 中级认证专家学习机构
  • DNS域名解析服务器--RHCE
  • 使用SaaS化的Aurora应用快速搭建私人ChatGPT助手
  • Deep Fake Detection (DFD) Entire Original Dataset数据集下载