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、…...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...

R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

C++实现分布式网络通信框架RPC(2)——rpc发布端
有了上篇文章的项目的基本知识的了解,现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一:HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二:Floyd 快慢指针法(…...
TCP/IP 网络编程 | 服务端 客户端的封装
设计模式 文章目录 设计模式一、socket.h 接口(interface)二、socket.cpp 实现(implementation)三、server.cpp 使用封装(main 函数)四、client.cpp 使用封装(main 函数)五、退出方法…...

2025年- H71-Lc179--39.组合总和(回溯,组合)--Java版
1.题目描述 2.思路 当前的元素可以重复使用。 (1)确定回溯算法函数的参数和返回值(一般是void类型) (2)因为是用递归实现的,所以我们要确定终止条件 (3)单层搜索逻辑 二…...
Easy Excel
Easy Excel 一、依赖引入二、基本使用1. 定义实体类(导入/导出共用)2. 写 Excel3. 读 Excel 三、常用注解说明(完整列表)四、进阶:自定义转换器(Converter) 其它自定义转换器没生效 Easy Excel在…...