MySQL--C_C++语言连接访问

Connector/C的使用

首先需要在mysql官网下载C接口库

解压指令

tar -zxvf 压缩包名

下载并解压好后

 但是还有比这更优的做法。

这样子手动安装不仅麻烦,还可能存在兼容性的问题。

其实在我们使用yum安装mysql时,大概率会自动帮我们把其他的环境都安装下来并配置好

sudo yum install -y mysql-community-server

如果没有安装好,那么我们也可以单独安装

yum install myslq-devel

安装好后,查看

ls /usr/include/mysql

可以看到头文件就都在默认的搜索目录下了

那么我们就可以开始写代码了,注意包含头文件的方式

简单使用 

#include <iostream>
#include <mysql/mysql.h>int main()
{printf("mysql client Version: %s\n", mysql_get_client_info());return 0;
}

makefile

test:test.ccg++ -o $@ $^ -std=c++11 -L/lib64/mysql -lmysqlclient.PHONY:cleanclean:rm -f test

编译指令记得指明库所在的位置以及指明需要链接哪个库 

-I(大写的i),在编译时可以告诉g++我们的头文件位置在哪里,这样的话我们包头文件可以直接包。

运行结果

ldd ./test

 可以查看这个程序链接了那些库

用C_C++进行增删改

首先我们需要创建一个MYSQL对象,并对它进行初始化,并在不用的时候记得释放。 

然后因为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);//后两个字段可以设置为nullptr和0//建立好链接之后,获取英文没有问题,如果获取中文是乱码:
//设置链接的默认字符集是utf8,原始默认是latin1
mysql_set_character_set(myfd, "utf8");

示例:

#include <iostream>
#include <string>
#include <mysql/mysql.h>
#include <unistd.h>const std::string host = "127.0.0.1";
const std::string user = "chika";
const std::string password = "3412741074";
const std::string db = "test_db";
const int port = 3306;int main()
{//printf("mysql client Version: %s\n", mysql_get_client_info());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(),password.c_str(),db.c_str(),port,nullptr,0) == nullptr){std::cerr << "mysql connect error" << std::endl;return 2;}std::cout<< "mysql connect success" << std::endl;sleep(5);mysql_close(my);return 0;
}

记得事先将自己的mysql服务启动。另外ip地址我们用的是本地环回地址,如果是本地链接,也可以改为 "localhost" 。

在mysql这边,我们可以用

show processlist;

来查看当前mysql的链接情况。

 首先我们先在本地mysql上创建一张测试表

create table test(id int primary key auto_increment,name varchar(25) not null,qq varchar(30));

 mysql_query()可以向mysql使其执行增删改查操作。

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

第一个参数就是我们创建的mysql对象,第二个参数就是我们将要执行的命令。并且,这个命名是可以不带 ; 的。

成功返回0,失败返回非0值。

比如我们插入一条数据

#include <iostream>
#include <string>
#include <mysql/mysql.h>
#include <unistd.h>const std::string host = "127.0.0.1";
const std::string user = "chika";
const std::string password = "3412741074";
const std::string db = "test_db";
const int port = 3306;int main()
{//printf("mysql client Version: %s\n", mysql_get_client_info());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(),password.c_str(),db.c_str(),port,nullptr,0) == nullptr){std::cerr << "mysql connect error" << std::endl;return 2;}//设置好utf8编码,防止中文乱码mysql_set_character_set(my, "utf8");std::string sql = "insert into test1 (name,qq) values('李三光','123456')";int n = mysql_query(my,sql.c_str());if(n == 0) std::cout << "success" << std::endl;else std::cout << "sql error" << std::endl;mysql_close(my);return 0;
}

makefile

test:test.ccg++ -o $@ $^ -std=c++11 -L/lib64/mysql -lmysqlclient.PHONY:clean
clean:rm -f test

 编译并执行后

 此时看看表中的数据

 发现成功的插入进来了。

那么删除和修改也是同一个道理,就不重复演示了。

另外增删改是最简单的,因为我们只需要看到执行结果就可以了。但是查询是最复杂的,我们不仅要确保执行成功,还要将结果打印出来,处理比较麻烦。 

查询的细节 

前面说了,我们查询的话,还需要将结果打印出来,那么这个结果其实是保存在第一个参数,也就是那个结构体里面的。

此时还需要用到一个函数

mysql_store_result() 

如果 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 **.就当成一个二维数组来用吧。

示例: 

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

在mysql中,我们每次查询出来的结果都是一个表结构,但这其实是被处理过后的结果。每次查询,mysql会先将所有的数据读取出来后,转化成字符串。

所以MYSQL_RES可以想象成一个三维数组,没一行代表的是表中的每一行信息。

每一个元素就是一个char**,它们又指向了char*,char*则最终指向了该表中某行某列的结果。 

 这个是跟表的内容相关的。

MYSQL_FIELD跟表的属性相关,它也是一个结构体。

在我们使用完了这个结果集之后,记得将其free掉。

mysql_free_result()函数就是这些API函数之一,其主要用途是释放一个MYSQL_RES结构所占用的内存。

void mysql_free_result(MYSQL_RES *result);

 浅谈一下mysql连接池

 我们知道mysql是网络服务,那么其他客户端想让mysql执行命令时需要先进行链接,为了提高效率,我们可以创建一个连接池,连接池里面有多个线程,每一个线程管理着一个mysql对象(已连接好mysqld的),然后循环等待任务。然后用户想进行操作时,就只需要打包一个task任务结构体,交给连接池,连接池把这个任务放在队列里面,让空闲的线程取走,把里面的sql交给musql执行。就是生产者消费者模型。这样就避免了每次sql都要重新建立链接的操作。

  另外关于查询,在task结构体里面可以设置一个回调函数,如果这是一个查询sql,那么可以通过这个回调函数把结果拿回来,这个回调函数是由用户这边设置好的。

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

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

相关文章

【Datawhale AI夏令营】电力需求预测挑战赛 Task01

整个学习活动&#xff0c;将带你从 跑通最简的Baseline&#xff0c;到了解竞赛通用流程、深入各个竞赛环节&#xff0c;精读Baseline与进阶实践 文章目录 一、赛题背景二、赛题任务三、实践步骤学习规划分析思路常见时序场景 task01codecode 解读 一、赛题背景 随着全球经济的…

CSA笔记1-基础知识和目录管理命令

[litonglocalhost ~]$ 是终端提示符&#xff0c;类似于Windows下的cmd的命令行 litong 当前系统登录的用户名 分隔符 localhost 当前机器名称&#xff0c;本地主机 ~ 当前用户的家目录 $ 表示当前用户为普通用户若为#则表示当前用户为超级管理员 su root 切换root权限…

昇思25天学习打卡营第12天|munger85

基于MindSpore通过GPT实现情感分类 这个实现情感分类意思就是通过一些电影的数据最后知道他对于这个电影的评价&#xff0c;最后知道他对于这个电影的评价到底是好还是不好&#xff0c;零就是不好&#xff0c;一就是好。首先我们肯定是按安装这些依赖包了为了今天这个模型我们…

【Apache Doris】周FAQ集锦:第 14 期

【Apache Doris】周FAQ集锦&#xff1a;第 14 期 SQL问题数据操作问题运维常见问题其它问题关于社区 欢迎查阅本周的 Apache Doris 社区 FAQ 栏目&#xff01; 在这个栏目中&#xff0c;每周将筛选社区反馈的热门问题和话题&#xff0c;重点回答并进行深入探讨。旨在为广大用户…

深度加速器 为游戏而生

使用深度加速器的基本步骤如下 首先&#xff0c;访问深度加速器的官方网站或授权下载渠道&#xff0c;下载最新版本的深度加速器客户端。 下载完成后&#xff0c;电脑版直接双击打开免安装&#xff0c;将深度加速器安装到您的计算机或移动设备上。 注册与登录&#xff1a; 打…

如何构建全生命周期的安全体系架构来确保容器的安全?

容器技术在云原生应用和微服务架构中得到了广泛应用&#xff0c;其轻量、灵活和高效的特点使其成为现代IT环境中的重要工具。然而&#xff0c;尽管容器带来了许多优势&#xff0c;但其安全性问题也不容忽视。接下来跟随博主一起探索如何构建全生命周期的安全体系架构以确保容器…

Vue3 子组件像父组件传递数据 自定义事件 defineEmits

介绍 很多情况下子组件都需要像父组件去传递一些数据&#xff0c;Vue3和Vue2传递值的写法不太一样。 例子 很常见的一个案例&#xff0c;弹出一个商品对话框&#xff0c;用户选择商品后把商品信息返回给父组件&#xff0c;使用自定义事件去做。 子组件 选择商品对话框 &…

数据库操作太复杂?Python Shelve模块让你轻松存储,一键搞定!

目录 1、基本操作入门 &#x1f4da; 1.1 安装Shelve模块 1.2 创建与打开Shelve文件 2、存储与读取数据 &#x1f510; 2.1 写入键值对 2.2 读取存储的数据 3、高级功能探索 &#x1f9ed; 3.1 使用Shelve迭代键和值 3.2 键的管理&#xff1a;添加、删除与更新 4、异…

详解曼达拉升级:如何用网络拓扑结构扩容BSV区块链

​​发表时间&#xff1a;2024年5月24日 BSV曼达拉升级是对BSV基础设施的战略性重塑&#xff0c;意在显著增强其性能&#xff0c;运行效率和可扩容。该概念于2018年提出&#xff0c;其战略落地将使BSV区块链顺利过渡&#xff0c;从现有的基于单一集成功能组件的网络拓扑结构&am…

MySQL面试篇章——MySQL基础复习

文章目录 MySQL基本介绍MySQL数据类型数值类型字符串类型日期和时间类型ENUM和SET MySQL运算符算数运算符逻辑运算符比较运算符 MySQL常用函数字符串函数数值函数时间和日期函数聚合函数 MySQL完整性约束范式第一范式&#xff08;1NF&#xff09;第二范式&#xff08;2NF&#…

有关电力电子技术的一些相关仿真和分析:⑤交-直-交全桥逆变+全波整流结构电路(MATLAB/Siumlink仿真)

全桥逆变+全波整流结构 参数:Vin=500V, Vo=200V, T=2:1:1, RL=10Ω, fs=100kHz, L=1mH, C=100uF (1)给定输入电压,输出电压和主电路参数,仿真研究电路工作原理,分析工作时序; (2)调节负载电阻,实现电流连续和断续,并仿真验证; (3)调节占空比,分析占空比与电…

设计模式总结(设计模式的原则及分类)

1.什么是设计模式&#xff1f; 设计模式(Design pattern)代表了最佳的实践&#xff0c;通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结…

SpringBoot中动态注册Bean的方式

测试环境&#xff0c;本文源码 Java&#xff1a;8SpringBoot&#xff1a;2.5.14示例场景&#xff1a;动态注册ProxyServlet&#xff0c;间接实现类似于Nginx的反向代理功能 先理解如何实现动态注册 Bean 。 由于在 SpringBoot 中&#xff0c;先进行 Bean 的定义&#xff0c;…

企业全历史行为数据助ToB企业决策层开启营销的上帝视角

“上帝视角”是每个企业家都渴望拥有的。上帝视角的能力有多么吸引人呢&#xff1f;通常&#xff0c;一个企业家在技术、产品、营销中的任何一个领域拥有上帝视角的能力&#xff0c;就足可以让他的企业大杀四方&#xff0c;甚至创造历史。 在技术或产品领域&#xff0c;靠“上…

沙袋装袋机的原理和特点_鼎跃安全

在现代工业和建筑领域&#xff0c;沙子等散状物料的包装是一个必不可少的环节。传统的手工包装方式效率低下且劳动强度大&#xff0c;而沙袋装袋机的出现则极大地提高了包装效率和质量。 一、沙袋装袋机的工作原理 沙子通过输送系统从储料仓输送到装袋机的料斗中。输送系统设计…

Eureka——Spring Cloud中的服务注册与发现组件

目录 1. 前言2. Eureka的概述2.1 Eureka的核心功能2.2 Eureka的角色与特点2.3 Eureka的使用优势 3. 创建 Spring Cloud 的注册中心3.1 创建一个父项目3.2 创建Spring Cloud的注册中心Eureka 4. 创建服务提供者5. 创建一个消费者Consumer&#xff0c;调用服务提供者Provider 1. …

java链表常见简单面试算法题

头插法、尾插法 头插法&#xff1a;先待插入指向头结点的next&#xff0c;后头结点的next指向待插入。 尾插法&#xff1a;借助尾指针&#xff0c;直接插入 /*** 头插法* param head* return*/public static Node head_insert(Node head, int t){Node nodenew Node(t);node.set…

【Diffusion学习】【生成式AI】Stable Diffusion、DALL-E、Imagen 背後共同的套路

文章目录 图片生成Framework 需要3个组件&#xff1a;相关论文【Stable Diffusion&#xff0c;DALL-E&#xff0c;Imagen】 具体介绍三个组件1. Text encoder介绍【结论&#xff1a;文字的encoder重要&#xff0c;Diffusion的模型不是很重要&#xff01;】评估指标&#xff1a;…

Webpack看这篇就够了

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…

补充.IDEA的使用

首先我们要了解在idea中Java工程由项目&#xff08;project&#xff09;、模块&#xff08;module&#xff09;包&#xff08;package&#xff09;、类&#xff08;class&#xff09;组成。 他们之间的关系是project包含module包含package包含class。 所以我们要按照先建一个pr…