详解MySQL C API 相关接口(大白话就是:MySQL的c语言怎么写)

文章目录

      • 1、C API 官方文档
      • 2、初始化 MYSQL
      • 3、连接 MySQL
        • 设置连接字符集(使得客户端编码方式匹配)
      • 4、下发 mysql 指令
      • 5、获取 mysql 查询结果(保存起来)
        • 获取行与列
        • 遍历存储结果
      • 6、释放 MYSQL\_RES 对象
      • 7、关闭 MySQL 连接
      • 8、总结

1、C API 官方文档

关于C语言连接数据所涉及到的各种数据结构的介绍以及相关函数的使用其实在 MySQL C API 官方文档中已经给出了,我们可以通过它来快速了解并上手 MySQL C API。

image-20231029131432088

image-20231029131530338

2、初始化 MYSQL

要使用 MySQL C语言库,需要先使用 mysql_init 函数完成对 MYSQL 结构体指针的初始化工作。

MYSQL *mysql_init(MYSQL *mysql)
  • 函数返回值:失败返回 NULL。

注意:mysql_init 函数的参数以及返回值都是 MYSQL 指针类型,对于 MYSQL,大家把它类比到C语言中的文件指针来理解即可。MYSQL 和C语言文件 FILE 一样,本质上都是一个结构体。

image-20231029133239373

image-20231029133254539

MYSQL *mfp = mysql_init(nullptr); if(mfp == nullptr) { cerr << "mysql init error" << endl; return 1; } cout << "mysql init success" << endl;

image-20231029140828078

注意:这里用C语言的 NULL 还是C++的 nullptr 都可以,因为它们在数值上都是0;区别在于在定义时 NULL 是一个整数,而 nullptr 则是被强转为了 void* 类型。

3、连接 MySQL

初始化完毕后,我们需要使用 mysql_real_connect 函数来连接数据库。

MYSQL *
mysql_real_connect(MYSQL *mysql,       // MYSQL结构体指针对象const char *host,   // mysqld服务进程所在的主机const char *user,   // 登录MySQL的用户const char *passwd, // 用户密码const char *db,     // 要访问的数据库unsigned int port,  // mysqld服务进程的端口号const char *unix_socket,    // 默认设为NULL即可unsigned long client_flag)  // 默认设为0即可
  • 函数返回值:失败返回0,成功返回传入的MYSQL指针。
#define HOST "127.0.0.1" //MySQL不允许远程访问 出于安全考虑 所以只可以使用本地网络 127.0.0.1
#define USER "li_zheng_yang"
#define PASS "Gaopengyan99999."
#define DBNAME "Five_in_a_row"
#define PORT 3306 //这是系统API接口默认的
if( mysql_real_connect(mysql,HOST,USER,PASS,DBNAME,PORT,NULL,0)==nullptr )//第一个参数叫句柄{cout << "connect failed" << endl;cout << mysql_error(mysql);//放入句柄 查看连接失败原因mysql_close(mysql);return -1;}

image-20231029140931672

设置连接字符集(使得客户端编码方式匹配)

需要注意的是,我们之前在创建数据库时默认使用的字符集是 utf8,而C语言连接数据时默认的字符集是 latin1 的(拉丁),这就会导致我们在向表中插入中文数据时,由于字符集不匹配,最终数据库中存储的数据显式出来是乱码。

所以,我们需要使用 mysql_set_character_set 函数设置连接字符集为 utf8

int mysql_set_character_set(MYSQL *mysql, const char *csname)
  • 函数返回值:返回0表示成功,非0表示失败。
int n = mysql_set_character_set(mfp, "utf8");
if(n != 0) { cout << "warning: character set fail" << endl; }

4、下发 mysql 指令

在成功连接到数据库之后,我们就可以通过 mysql_query 函数来下发 mysql 指令了。

int mysql_query(MYSQL *mysql, const char *stmt_str)
  • 函数返回值:执行成功返回0,失败返回非0。
	//增删改查 int mysql_query(MYSQL *mysql, const char *stmt_str) 这里的第二个参数前面必须加上 constconst char* sql="insert stu values(null,'lzy',21,100,100,100);";//const char* sql="update stu set ch=ch-1 where sn=1;";//const char* sql="delete from stu where sn=1;";int ret=mysql_query(mysql,sql);

需要注意的是,我们在使用 mysql client 时,一条 sql 语句需要以分号结尾;但是在C语言中,sql 语句可以不用带分号,当然带上也没事。

检验是否插入成功:

select* from stu;

image-20240425213855738

检验是否修改成功:

image-20240425214241180

5、获取 mysql 查询结果(保存起来)

我们上面是对数据库执行增删改操作,它们相对来说比较简单,因为我们只需要将指令下发给数据库即可,后面的事情我们不必关心。但==如果我们执行的是查询操作,则需要通过 mysql_store_result 函数来获取查询结果==。

MYSQL_RES *mysql_store_result(MYSQL *mysql)
  • 函数返回值:失败返回 NULL,成功返回一个非空的 MYSQL_RES 类型的结构体指针。

实际上,mysql_store_result 函数会调用 MYSQL 结构体变量中的 st_mysql_methods 字段中的 read_rows 函数指针来获取查询的结果;然后将查询结果保存到 MYSQL_RES 结构体中并返回结构体指针。这样,当执行完 mysql_store_result 以后,其实数据都已经在MYSQL_RES 变量中了,我们直接从中获取即可。

需要注意的是,MYSQL_RES 是通过 malloc/new 空间的方式来保存查询结果的,所以当我们使用完毕之后,一定要记得释放 MYSQL_RES 对象,否则就会造成内存泄漏。同时,MYSQL_RES 结构体中存在查询结果的列数、列信息、行数、行内容等属性,我们需要使用对应的函数来获取这些信息。

image-20231029152423987

获取行与列

unsigned int mysql_num_rows(MYSQL_RES *result)

unsigned int mysql_num_fields(MYSQL_RES *result)
遍历存储结果
for(int i=0;i<num_row;i++){//MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)MYSQL_ROW row=mysql_fetch_row(res);for(int i=0;i<num_col;i++){cout << row[i] << "\t";}cout << endl;}

当然,我们也可以通过调用 mysql_fetch_fields 函数一次获取到所有列的属性信息,然后分别打印。

MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);
  • 获取结果行数。
my_ulonglong mysql_num_rows(MYSQL_RES *result)

6、释放 MYSQL_RES 对象

由于 MYSQL_RES 保存查询结果的空间是通过 malloc/new 得到的,所以当我们使用完毕后需要释放掉 MYSQL_RES 对象,防止内存泄露。

void mysql_free_result(MYSQL_RES *result)
mysql_free_result(res);

7、关闭 MySQL 连接

最后,当我们使用完 MySQL 后,需要关闭 MySQL 之前建立的连接。

void mysql_close(MYSQL *sock);
mysql_close(mfp);

8、总结

使用 MySQL C API 连接数据库进行简单操作的步骤如下:

  1. 初始化 MYSQL 结构体指针 – mysql_init。
  2. 连接 MySQL – mysql_real_connect:需要指定数据库服务所在主机、端口以及登录mysql的用户和密码等信息。
  3. 下发 MySQL 指令 – mysql_query。
  4. 获取 MySQL 查询结果:将查询结果转储到 MYSQL_RES 中 – mysql_store_result,获取查询结果的行数 – mysql_num_rows,获取查询结果列数 – mysql_num_fields,获取单个/所有列字段的 MYSQL_FIELD 属性信息 – mysql_fetch_field/mysql_fetch_fields,获取查询结果单行的内容 (不包含属性行) – mysql_fetch_row。
  5. 释放 MYSQL_RES 对象 – mysql_free_result。
  6. 关闭 MySQL 连接 – mysql_close。
#include<bits/stdc++.h>
#include<mysql/mysql.h>
using namespace std;
#define HOST "127.0.0.1" //MySQL不允许远程访问 出于安全考虑 所以只可以使用本地网络 127.0.0.1
#define USER "root"
#define PASS "Gaopengyan99999."
#define DBNAME "Five_in_a_row"
#define PORT 3306 //这是系统API接口默认的
int main()
{1.初始化MySQL句柄MYSQL* mysql = mysql_init(nullptr);//MYSQL *mysql_init(MYSQL *mysql) 传空 那么就是堆上申请空间//MYSQL 和C语言文件 FILE 一样,本质上都是一个结构体 所以mysql就相当于是结构体创建的节点 //类似于 ListNode* nodeif(mysql==nullptr){cout << "create fail" << endl;return -1;}/2.连接服务器/*MYSQL * mysql_real_connect(MYSQL *mysql,       // MYSQL结构体指针对象const char *host,   // mysqld服务进程所在的主机const char *user,   // 登录MySQL的用户const char *passwd, // 用户密码const char *db,     // 要访问的数据库unsigned int port,  // mysqld服务进程的端口号const char *unix_socket,    // 默认设为NULL即可unsigned long client_flag)  // 默认设为0即可*/if( mysql_real_connect(mysql,HOST,USER,PASS,DBNAME,PORT,NULL,0)==nullptr )//第一个参数叫句柄{cout << "connect failed" << endl;cout << mysql_error(mysql);//放入句柄 查看连接失败原因mysql_close(mysql);return -1;}/3.设置客户端字符集///if( mysql_set_character_set(mysql,"utf8") != 0 ) //文档规定 为0则为成功 非0则失败了{cout << "set character failed" << endl;cout << mysql_error(mysql);//放入句柄 查看连接失败原因mysql_close(mysql);return -1;}/4.选择要操作的数据库///这一步不需要进行了 我们在连接服务器的时候实则已经默认选择过了//mysql_select_db(mysql,DBNAME);//5.执行sql语句////增删改查 int mysql_query(MYSQL *mysql, const char *stmt_str) 这里的第二个参数前面必须加上 const//const char* sql="insert stu values(null,'lzy',21,100,100,100);";//const char* sql="update stu set ch=ch-1 where sn=1;";//const char* sql="delete from stu where sn=1;";const char* sql="select * from stu;";int ret=mysql_query(mysql,sql);if( ret!=0 )//查询和增删改不一样 得保存数据到本地{cout << "find failed" << endl;cout << mysql_error(mysql);//放入句柄 查看连接失败原因mysql_close(mysql);return -1;}///6.select保存结构到本地/MYSQL_RES *res=mysql_store_result(mysql);if( res == nullptr){mysql_close(mysql);return -1;}//7.获取行数与列数//unsigned int mysql_num_fields(MYSQL_RES *result)//unsigned int mysql_num_rows(MYSQL_RES *result)int num_row=mysql_num_rows(res);//res是上面用mysql_store_result获取出来保存进去的结果int num_col=mysql_num_fields(res);//8.遍历读取数据for(int i=0;i<num_row;i++){//MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)MYSQL_ROW row=mysql_fetch_row(res);for(int i=0;i<num_col;i++){cout << row[i] << "\t";}cout << endl;}//9.释放结果集///mysql_free_result(res);/10.关闭连接/mysql_close(mysql);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/3309.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

动态规划---斐波那契数列模型

目录 一、斐波那契数列的基本概念 二、动态规划在斐波那契数列中的应用与优势 三、实际案例&#xff1a;使用动态规划解决斐波那契数列问题 四、动态规划问题的做题步骤 五、例题 1、第N个泰波那契数---点击跳转题目 2、三步问题----点击跳转题目 3、最小花费爬楼梯---…

FANUC机器人socket通讯硬件配置

一、添加机器人选配包 Fanuc机器人要进行socket通讯&#xff0c;需要有机器人通讯的选配包&#xff0c;1A05B-2600-R648 User Socket Msg&#xff0c;1A05B-2600-R632 KAREL&#xff0c;1A05B-2600-R566 KAREL Diagnostic&#xff0c;1A05B-2600-J971 KAREL Use Sprt FCTN。 二…

【漏洞复现】WebLogic XMLDecoder反序列化(CVE-2017-10271)

1、漏洞描述 CVE-2017-10271漏洞产生的原因大致是Weblogic的WLS Security组件对外提供webservice服务&#xff0c;其中使用了XMLDecoder来解析用户传入的XML数据&#xff0c;在解析的过程中出现反序列化漏洞&#xff0c;导致可执行任意命令。攻击者发送精心构造的xml数据甚至能…

clickhouse数据去重函数介绍(count distinct)

非精确去重函数&#xff1a;uniq、uniqHLL12、uniqCombined 精确去重函数&#xff1a;uniqExact、groupBitmap 测试数据量&#xff1a;2000w 结论&#xff1a; 1.整形值精确去重场景&#xff0c;groupBitmap 比 uniqExact至少快 2x 2.groupBitmap仅支持无符号整形值去重&#x…

文化旅游3D数字孪生可视化管理平台推动文旅产业迈向更加美好的未来

随着数字化、智能化管理成为文旅产业发展的必然趋势&#xff0c;数字孪生公司深圳华锐视点创新性地推出了景区三维可视化数字孪生平台&#xff0c;将线下的实体景区与线上的虚拟世界完美融合&#xff0c;引领智慧文旅新潮流。 我们运用先进的数字孪生、web3D开发和三维可视化等…

详解Qt中的鼠标事件

在Qt中&#xff0c;处理鼠标事件是构建交互式界面的关键。Qt提供了一系列与鼠标相关的事件处理函数&#xff0c;允许开发者捕获鼠标的各种动作&#xff0c;如按下、释放、移动、双击等。以下是鼠标事件的使用方法、技巧以及注意事项&#xff0c;并附带C代码示例。 基础使用方法…

GDB多线程调试:Redis的IO多线程

Redis采用的网络模型是单线程的Reactor网络模型&#xff0c;异步处理&#xff0c;因为性能很高。 Reactor先从客户端获取请求&#xff0c;然后dispatch给具体的执行的线程。处理的流程即为read->decode->compute->encode->send。 而Redis的IO多线程的处理时&…

【C++】:拷贝构造函数和赋值运算符重载

目录 一&#xff0c;拷贝构造函数1. 什么是拷贝构造函数2. 拷贝构造函数的特性3. 实践总结 二&#xff0c;赋值运算符重载2.1 运算符重载2.2 赋值运算符重载 一&#xff0c;拷贝构造函数 1. 什么是拷贝构造函数 拷贝构造函数是特殊的构造函数。是用一个已经存在的对象&#x…

SAP采购订单-条件类型-配置开发步骤

由于采购业务变更&#xff0c;需要创建新的价格类型&#xff0c;并添加新的计算逻辑计算。首先在例程&#xff08;VOFM&#xff09;中创建计算逻辑&#xff0c;然后在系统配置&#xff08;SPRO&#xff09;中找到配置点&#xff0c;创建新的条件类型‘ZMM00’,创建定价过程‘ZM…

SpringCloud系列(16)--将服务提供者Provider注册进Zookeeper

前言&#xff1a;在上一章节中我们说明了一些关于Eureka自我保护模式&#xff0c;而且自上一章节起关于Eureka的知识已经讲的差不多了&#xff0c;不过因为Eureka已经停更了&#xff0c;为了安全考虑&#xff0c;我们要用还在更新维护的注册中心来取代Eureka&#xff0c;而本章…

Flink面试(2)

Flink面试&#xff08;1&#xff09;-CSDN博客 9. Flink 状态如何存储&#xff1f; 在 Flink 中&#xff0c;状态存储 被叫做 StateBackend&#xff0c;它具备两种能力&#xff1a; 在计算过程中提供访问 State 能力&#xff0c;开发者在编写业务逻辑中能够使用 StateBacken…

网络数据包嗅探器工具

组织的网络非常庞大&#xff0c;包含服务器、交换机、路由器和接入点等众多节点&#xff0c;由于许多资源和流量不断通过这些节点&#xff0c;因此很难确定大量流量是真实的还是安全攻击的迹象&#xff0c;了解和了解组织的网络流量至关重要&#xff0c;一个有用的资源是网络数…

MySQL--mysql的安装(压缩包安装保姆级教程)

官网下载&#xff1a;www.mysql.com MySQL :: Download MySQL Community Server (Archived Versions) 1.MySQL下载流程&#xff1a; 第一步&#xff1a;点击download&#xff0c; 下滑找到MySQL community&#xff08;gpl&#xff09;Downloads>> 第二步&#xff1a;点…

通俗易懂,十分钟让你了解并上手 Docker

通俗易懂&#xff0c;十分钟让你了解并上手 Docker 一、Docker 能拿来解决什么问题二、Docker 的概念与模型1. 容器化技术2. 镜像的概念3. Docker与虚拟机 三. Docker的使用1. 环境安装2. 制作镜像3. 镜像管理&#xff08;1&#xff09; 图形界面&#xff08;2&#xff09; 命令…

Coursera: An Introduction to American Law 学习笔记 Week 03: Property Law

An Introduction to American Law 本文是 https://www.coursera.org/programs/career-training-for-nevadans-k7yhc/learn/american-law 这门课的学习笔记。 文章目录 An Introduction to American LawInstructors Week 03: Property LawKey Property Law TermsSupplemental Re…

多功能气象传感器解析

TH-WQX5多功能气象传感器在监测要素上越来越丰富。除了传统的温度、湿度、风速、风向等基本气象要素外&#xff0c;现代的多功能气象传感器还能够监测降雨量、大气压力、光照强度、紫外线强度、土壤温湿度等多种参数。这些数据的获取&#xff0c;使得农业生产者能够更全面地了解…

4款值得推荐的AI辅助编程工具(支持C#语言)

前言 在这个AI迅速发展的阶段&#xff0c;涌现出了一大批好用的AI辅助编程工具。AI辅助编程工具能够提高开发效率、改善代码质量、降低bug率&#xff0c;是现代软件开发过程中的重要助手。今天大姚给大家分享4款AI辅助编程工具&#xff08;并且都支持C#语言&#xff09;&#x…

ChromaDB教程

使用 Chroma DB&#xff0c;管理文本文档、将文本嵌入以及进行相似度搜索。 随着大型语言模型 &#xff08;LLM&#xff09; 及其应用的兴起&#xff0c;我们看到向量数据库越来越受欢迎。这是因为使用 LLM 需要一种与传统机器学习模型不同的方法。 LLM 的核心支持技术之一是…

Linux 文件/目录管理(头歌实训)

目录 任务描述 相关知识 Linux 创建文件 Linux 删除文件 编程要求 测试说明 任务描述 相关知识 Linux 创建目录 Linux 删除目录 编程要求 测试说明 任务描述 相关知识 Linux 拷贝文件 Linux 重命名文件 编程要求 测试说明 任务描述 相关知识 Linux 拷贝目…

初入数据库

SQL&#xff1a;操作关系型数据库的编程语言&#xff0c;定义了一套操作关系型数据库的统一标准。 DDL&#xff08;Data Definition Language&#xff09;数据定义语言 数据库 show databases;create database db01;use db01;select database(); 显示当前使用的数据库drop d…