C++ 二进制图片的读取和blob插入mysql_stmt_init—新年第一课
关于二进制图片的读取和BLOB插入一共包含五步
第一步:初始化
MYSQL_STMT* stmt = mysql_stmt_init(&mysql);
第二步:预处理sql语句
mysql_stmt_prepare(stmt,sql,sqllen);
第三步:绑定字段
mysql_stmt_bind_param(stmt,bind);
第四步:执行
mysql_stmt_excute(stmt);
第五步:关闭
mysql_stmt_close(stmt);
详细步骤如下:
1、连接数据库;这个就不详细讲解了
const char* host = "127.0.0.1";const char* user = "root";const char* password = "************";const char* database = "database_test";int port = 3306;MYSQL mysql;mysql_init(&mysql);mysql_library_init(0, NULL, NULL);//防止乱码mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "GBK");//支持多条sql语句 CLIENT_MULTI_STATEMENTS clientflag 默认是不支持的//if (!mysql_real_connect(&mysql, host, user, password, database, port, 0, 0))if (!mysql_real_connect(&mysql, host, user, password, database, port, NULL, 0)){cout << "failed to connect" << host << mysql_error(&mysql) << endl;}else{cout << "successfully connected " << host <<endl;}
2、创建数据表t_data; 创建好存放二进制数据的表 t_data
注意***:这里的数据类型,必须是blob. 其他和以前一样
//创建号存放二进制数据的表 t_datastring sql = "";sql="CREATE TABLe IF NOT EXISTS `t_data`(\`id` int AUTO_INCREMENT,\`name` varchar(1024),\`data` blob,\`size` int,\PRIMARY KEY(id)\)";int re = mysql_query(&mysql, sql.c_str());if (re != 0){cout << "failed mysql_error" << mysql_error(&mysql) << endl;}
3、初始化stmt
MYSQL_STMT*stmt=mysql_stmt_init(&mysql);
4、预处理sql语句
// 注意这里的插入必须是???
sql="insert into t_data (name,data,size) values (?,?,?)";
//错误输出是mysql_stmt_error(stmt);和之前不一样哦;
//sql语句,插入数据
// 注意这里的插入必须是???sql = "insert into `t_data` (name,data,size) values (?,?,?)";if (mysql_stmt_prepare(stmt, sql.c_str(), sql.size())){cerr << "mysql_stmt_prepare failed!" << mysql_stmt_error(stmt) << endl;}
5、绑定字段
MYSQL_BIND bind[3]={ 0 };//第一个数据name
bind[0].buffer_type = MYSQL_TYPE_STRING; //name文件名
bind[0].buffer = (char*)filename.c_str();//原图的文件名
bind[0].buffer_length = filename.size();
//(char*) buffer要求的是void*,而c_str()是只读的,所以要转换char*。
//而bind是可以输入可以输出,所以不可以只读。默认const是只读的,但是在这儿是插入数据,不会修改数据,可以用char*bind[1].buffer_type = MYSQL_TYPE_BLOB;// data 文件二进制内容
bind[1].buffer = data; //二进制文件
bind[1].buffer_length = filesize; //文件大小//把文件大小存下来
//从mysql取出来,可以知道文件大小,但是不一定将它取出来,
//经常做显示文件列表,有时候不需要显示二进制。希望有个字段将文件大小存下来bind[2].buffer_type = MYSQL_TYPE_LONG;//长整型,不用直到size,因为是固定大小
bind[2].buffer = &filesize; //存放指针
5.1、如何filename 和data?
在上述代码的前面需要定义filename和data大小;
//4、打开并读取文件string filename = "mysql.jpg";//打开文件可以有多种方式,可以用c的file fopen,但是这个在vs2017里面说不安全,得设置不安全选项//fopen_s 是多线程安全版本的,到了linux又不行了//为了跨平台,用C++方式读取 fstream//需要知道文件大小和文件二进制 考虑到空间的分配和释放 动态空间//int filesize = 0;//ios::binary必须写,因为是二进制文件,如果是文本文件,无所谓不用加,但是还是加着fstream in(filename, ios::in | ios::binary);//文件是否存在if (!in.is_open()){cerr << "file" << filename << "open failed" << endl;}//fopen//句柄,文件指针移到结尾处//从结尾往前移动,移动0个位置,也就是结尾//判断位置in.seekg(0, ios::end);// 得到文件大小,//文件大小和文件二进制int filesize = in.tellg();//得到大小之后,将文件移到开头,要不然待会读文件就读不到了in.seekg(0, ios::beg);//分配空间大小char* data = new char[filesize];//查看是否读完,不保证一次读完,所以用循环读,可以直到读取了多少int readed = 0;//已经读了多少while (!in.eof()){//in.read(data, filesize); data读什么数据,filesize读多少//指针要进行移位in.read(data + readed, filesize - readed);//上次读了多少字节if (in.gcount()<=0){break;}readed += in.gcount();}in.close();
6、绑定 mysql_stmt_bind_param(stmt, bind)
//6、绑定if (mysql_stmt_bind_param(stmt, bind)!=0) //定义和文档不一致,=表示成功{//cerr错误输出,在重定向的时候,可以分割开来,也可以写到文件当中//cout 标准输出/*cout:写到标准输出的ostream对象;cerr:输出到标准错误的ostream对象,常用于程序错误信息;clog:也是输出标准错误流(这点儿和cerr是一样的),貌似平时很少用到这个啊;*/cerr << "mysql_stmt_bind_param failed" << mysql_stmt_error(stmt) << endl;}
7、执行stmt sql
//7、执行stmt sqlif (mysql_stmt_execute(stmt) != 0){//cerr错误输出cerr << "mysql_stmt_execute failed" << mysql_stmt_error(stmt) << endl;}
8、关闭stmt
mysql_stmt_close(stmt);
9、注意****
9.1、刚才申请了data空间是动态控件,必须要释放
delete []data;
9.2、在读取文件之后,一定要把文件关闭
in.close();
完整代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<stdio.h>
#include<mysql.h>
#include<thread>
#include<map>
#include<sstream>
#include<fstream>
//计时
#include<chrono>
using namespace std;
using namespace chrono;int main()
{const char* host = "127.0.0.1";const char* user = "root";const char* password = "*********"; //输入自己数据库的密码const char* database = "database_test";int port = 3306;MYSQL mysql;mysql_init(&mysql);mysql_library_init(0, NULL, NULL);//防止乱码mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "GBK");//支持多条sql语句 CLIENT_MULTI_STATEMENTS clientflag 默认是不支持的//if (!mysql_real_connect(&mysql, host, user, password, database, port, 0, 0))if (!mysql_real_connect(&mysql, host, user, password, database, port, NULL, 0)){cout << "failed to connect" << host << mysql_error(&mysql) << endl;}else{cout << "successfully connected " << host <<endl;}//blob blob存放二进制// int 最大值大概是2g//1、创建号存放二进制数据的表 t_datastring sql = "";sql="CREATE TABLe IF NOT EXISTS `t_data`(\`id` int AUTO_INCREMENT,\`name` varchar(1024),\`data` blob,\`size` int,\PRIMARY KEY(id)\)";int re = mysql_query(&mysql, sql.c_str());if (re != 0){cout << "failed mysql_error" << mysql_error(&mysql) << endl;}//2、初始化MYSQL_STMT* stmt = mysql_stmt_init(&mysql);//3、预处理sql语句sql = "insert into `t_data` (name,data,size) values (?,?,?)";if (mysql_stmt_prepare(stmt, sql.c_str(), sql.size())){cerr << "mysql_stmt_prepare failed!" << mysql_stmt_error(stmt) << endl;}//4、打开并读取文件string filename = "mysql.jpg";//打开文件可以有多种方式,可以用c的file fopen,但是这个在vs2017里面说不安全,得设置不安全选项//fopen_s 是多线程安全版本的,到了linux又不行了//为了跨平台,用C++方式读取 fstream//需要知道文件大小和文件二进制 考虑到空间的分配和释放 动态空间//int filesize = 0;//ios::binary必须写,因为是二进制文件,如果是文本文件,无所谓不用加,但是还是加着fstream in(filename, ios::in | ios::binary);//文件是否存在if (!in.is_open()){cerr << "file" << filename << "open failed" << endl;}//fopen//句柄,文件指针移到结尾处//从结尾往前移动,移动0个位置,也就是结尾//判断位置in.seekg(0, ios::end);// 得到文件大小,//文件大小和文件二进制int filesize = in.tellg();//得到大小之后,将文件移到开头,要不然待会读文件就读不到了in.seekg(0, ios::beg);//分配空间大小char* data = new char[filesize];//查看是否读完,不保证一次读完,所以用循环读,可以直到读取了多少int readed = 0;//已经读了多少while (!in.eof()){//in.read(data, filesize); data读什么数据,filesize读多少//指针要进行移位in.read(data + readed, filesize - readed);//上次读了多少字节if (in.gcount()<=0){break;}readed += in.gcount();}in.close();//5、绑定字段MYSQL_BIND bind[3] = { 0 };bind[0].buffer_type = MYSQL_TYPE_STRING; //name文件名//(char*) buffer要求的是void*,而c_str()是只读的,所以要转换char*。//而bind是可以输入可以输出,所以不可以只读。默认const是只读的,但是在这儿是插入数据,不会修改数据,可以用char*bind[0].buffer = (char*)filename.c_str();//原图的文件名bind[0].buffer_length = filename.size();bind[1].buffer_type = MYSQL_TYPE_BLOB;// data 文件二进制内容bind[1].buffer = data; //二进制文件bind[1].buffer_length = filesize; //文件大小//把文件大小存下来//从mysql取出来,可以知道文件大小,但是不一定将它取出来,//经常做显示文件列表,有时候不需要显示二进制。希望有个字段将文件大小存下来bind[2].buffer_type = MYSQL_TYPE_LONG;//长整型,不用直到size,因为是固定大小bind[2].buffer = &filesize; //存放指针//6、绑定if (mysql_stmt_bind_param(stmt, bind)!=0) //定义和文档不一致,=表示成功{//cerr错误输出,在重定向的时候,可以分割开来,也可以写到文件当中//cout 标准输出/*cout:写到标准输出的ostream对象;cerr:输出到标准错误的ostream对象,常用于程序错误信息;clog:也是输出标准错误流(这点儿和cerr是一样的),貌似平时很少用到这个啊;*/cerr << "mysql_stmt_bind_param failed" << mysql_stmt_error(stmt) << endl;}//7、执行stmt sqlif (mysql_stmt_execute(stmt) != 0){//cerr错误输出cerr << "mysql_stmt_execute failed" << mysql_stmt_error(stmt) << endl;}delete [] data;mysql_stmt_close(stmt);mysql_close(&mysql);mysql_library_end();system("pause");return 0;
}
插入成功

相关文章:
C++ 二进制图片的读取和blob插入mysql_stmt_init—新年第一课
关于二进制图片的读取和BLOB插入一共包含五步 第一步:初始化 MYSQL_STMT* stmt mysql_stmt_init(&mysql); 第二步:预处理sql语句 mysql_stmt_prepare(stmt,sql,sqllen); 第三步:绑定字段 mysql_stmt_bind_param(stmt,bind); 第四…...
向爬虫而生---Redis 基石篇2 <拓展Hash>
前言: 延续上一篇向爬虫而生---Redis 基石篇 <拓展str>-CSDN博客 这个章节拓展一下hash的玩法,主要是要挖一挖 ,啥时候用它最合适;让他并不是一无是处.. 正文: 哈希(Hash)数据结构是Redis中的一种常用的数据类型。它是一个键值…...
【论文精读】A Survey on Large Language Model based Autonomous Agents
A Survey on Large Language Model based Autonomous Agents 前言Abstract1 Introduction2 LLM-based Autonomous Agent Construction2.1 Agent Architecture Design2.1.1 Profiling Module2.1.2 Memory ModuleMemory StructuresMemory FormatsMemory Operations 2.1.3 Plannin…...
23款奔驰GLC260L升级原厂540全景影像 高清环绕的视野
嗨 今天给大家介绍一台奔驰GLC260L升级原厂360全景影像 新款GLC升级原厂360全景影像 也只需要安装前面 左右三个摄像头 后面的那个还是正常用的,不过不一样的是 升级完成之后会有多了个功能 那就是新款透明底盘,星骏汇小许Xjh15863 左右两边只需要更换后…...
SQL 在已有表中修改列名的方法
文章目录 1. MySQL2. SQL Server3. Oracle / PostgreSQL Question: 假设有一张表 StudentInfo,表中有一个列名是 Student_Name ,想要把这个列名改成 StudentName 应该如何操作? 建表语句如下: --建表 if object_id(S…...
QT----Visual stdio翻金币案例,附源码
历经一个月,各种事情磕磕绊绊,终于结束了,自己还是太菜了 案例的文档写的教程已经很详细,这边主要是记录一些问题 github代码 gitee代码 1、图片无法加载 一开始加载首页图片和标题出不来,结果是paintEvent重写的字打…...
总结:浏览器解析html与执行JS之生命周期详解
总结:浏览器解析html与执行JS之生命周期详解 一浏览器解析html的生命周期:1.请求HTML文档:2接收响应:3构建DOM树:4加载外部资源:5DOMContentLoaded事件:6样式计算与布局:7绘制与渲染…...
aspose通过开始和结束位置关键词截取word另存为新文件
关键词匹配实体类: Data EqualsAndHashCode(callSuper false) public class TextConfig implements Serializable {private static final long serialVersionUID 1L;/*** 开始关键词,多个逗号分隔*/private String textStart ;/*** 结束关键词&#x…...
深入解析美颜SDK:绿幕抠图功能的算法原理
当下,美颜SDK绿幕抠图功能成为许多应用中不可或缺的一环。本文将深入解析美颜SDK中绿幕抠图功能的算法原理,揭示其背后的技术奥秘。 一、什么是美颜SDK绿幕抠图? 美颜SDK的绿幕抠图功能是一种通过计算机视觉技术,将视频或图像中…...
从有向带权图判断最短路径里各目标顶点顺序
对如下有向带权图,若采用迪杰斯特拉(Dijkstra)算法求从源点a到其他各顶点的最短路径,则得到的第一路径的目标顶点是b,第二条最短路径的目标顶点是c,后续得到的其余各最短路径的目标顶点依次是() A.d,e,f B.e,d,f C.f,d,e D.f,…...
鼠标驱动框架:模拟键盘按键
/* 参考: drivers\hid\usbhid\usbmouse.c */ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/init.h> #include <linux/usb.h> #include <linux/input.h> #include <linux/hid.h>st…...
ES6之Promise的链式调用
✨ 专栏介绍 在现代Web开发中,JavaScript已经成为了不可或缺的一部分。它不仅可以为网页增加交互性和动态性,还可以在后端开发中使用Node.js构建高效的服务器端应用程序。作为一种灵活且易学的脚本语言,JavaScript具有广泛的应用场景&#x…...
HTML----JavaScript操作对象BOM对象
文章目录 目录 文章目录 本章要求 一.BOM模型概述 二.BOM核心:window对象 常用属性 常用方法: confirm() 案例 open ()close()案例 setTimeout( ) 案例 setInterval( ) 案例 document对象 练习 本章要求 了解BOM模型掌握BOM模型实际应用 一.BOM模型…...
隆道数智大会回顾|第13期《如何构建绿色产业供应链新生态》(完)
本期演讲嘉宾: 史文月 采购与供应链专家 邢庆峰 品类管理和质量管理专家 刘婷婷 中兴通讯供应链规划总监 张燕华 正大生物CIO 吴树贵 隆道公司总裁 本期演讲主题: 如何构建绿色产业供应链新生态 本期内容要点: 1.供应链管理的核心问…...
粒子群优化pso结合bp神经网络优化对csv文件预测matlab(3)
1.csv数据为密西西比数据集,获取数据集可以管我要,数据集内容形式如下图: 2.代码 这里参考的是b站的一位博主。 数据集导入教程在我的另一篇文章bp写过,需要的话可以去看一下 psobp.m close all clc%读取数据 inputX; outputY;…...
软性演员-评论家算法 SAC
软性演员-评论家算法 SAC 软性演员-评论家算法 SAC优势原理软性选择模型结构目标函数重参数化熵正则化代码实现 软性演员-评论家算法 SAC 优势原理 DDPG 的问题在于,训练不稳定、收敛差、依赖超参数、不适应复杂环境。 软性演员-评论家算法 SAC,更稳定…...
Nginx多域名部署多站点
目录 1.修改配置文件nginx.conf 2. 修改hosts文件 1.修改配置文件nginx.conf 在配置文件的 server_name 处修改成自己需要的域名,然后保存退出 j 查看语法是否错误,然后重启nginx nginx -t # 查看语法是否正确 systemctl restart nginx # 重启nginx …...
Java的常规面试题
Java的面试题主要涉及Java基础知识、并发编程、集合原理、JVM原理、I/O与网络编程、设计模式、互联网常用框架等多个领域[6]。一些常见的面试问题包括: 1. 面向对象的特征:继承、封装和多态性。 2. 访问修饰符public、private、protected以及默认时的区别…...
大数据技术发展史
文章目录 Google论文HadoopHive大数据生态 Google论文 今天我们常说的大数据技术,其实起源于Google在2004年前后发表的三篇论文,也就是我们经常听到的“三驾马车”,分别是分布式文件系统GFS、大数据分布式计算框架MapReduce和NoSQL数据库系统…...
linux常见基础指令
入门常见基础指令 ls、stat、 pwd 、cd、tree、 whoami、 touch、 mkdir、 rm 、 man、 cp、mv、cat、tac、echo、>、 >>、 < 、more、 less、 head、 tail、date、 cal、 find、 which、alias、whereis、grep、zip与unzip、 tar、bc、uname、xargs... 热键Tab、…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
