C++使用SQLite3心得 -- sqlite3以二进制形式存取图片(MFC,CppSQLite3U封装类)

本文主要是介绍C++使用SQLite3心得 -- sqlite3以二进制形式存取图片(MFC,CppSQLite3U封装类),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

实现功能:1.将图片文件(.jpg)以二进制形式存储到sqlite3里面2.从sqlite3里面读取二进制形式的图片数据并保存到图片文件(.jpg)

*注:本人超级菜鸟 此博客是为了总结用 仅仅说明了函数作用 可能直接编译不过 见谅 文中有何不妥之处 还望各位读者不吝赐教

一、创建/打开 sqlite3数据库 并 创建/打开 表

C++
// 打开sqlite3数据库(用CppSQLite3U类的方式)// 定义表名称#define TABLENAME _T("tb")// 声明数据库类型的全局变量CppSQLite3DB g_db;// 获取当前程序路径 并加上数据库名称CString strDbPath;CString strDbName(_T("test1.db"));GetCurrentDirectory( strDbPath );strDbPath += strDbName;// 创建/打开 数据库 若不存在则创建try{g_db.open(strDbPath);}catch(CppSQLite3Exception ex){g_db.execDML(L"rollback transaction;");}// 创建表// 判断表名是否已经存在CString strTbSql;CString strTbName(TABLENAME);try{if(!g_db.tableExists(strTbName)){  // 不存在,新建表tbstrTbSql.Format(_T("CREATE TABLE %s(ID INTEGER PRIMARY KEY, image BLOB);"), strTbName);// 执行SQL语句g_db.execDML(strTbSql);strTbSql.Empty();strTbSql.Format(_T("表%s创建成功!"), strTbName);::AfxMessageBox(strTbSql);}else{strTbSql.Format(_T("表%s已经存在!"), strTbName);::AfxMessageBox(strTbSql);}}catch(CppSQLite3Exception ex){g_db.execDML(L"create table exception!");}

二、然后拿到图片文件 打开图片文件并保存到sqlite3数据库中

C++
// 把图片文件以二进制形式保存到sqlite3数据库中// 拿到C盘下pic1.jpg图片的路径CString strFilePath(_T("C:\\pic1.jpg"));// 读取图片并开辟一块缓冲区以二进制形式存放图片CFile file;file.Open(strFilePath, CFile::typeBinary | CFile::modeRead);int nFileSize = file.GetLength();BYTE *pbytBuffer = new BYTE[nFileSize];file.Read(pbytBuffer, nFileSize);// 创建SQL语句 并利用stmt准备完毕// CppSQLite3U 是从网上找的一个封装了sqlite3的类 百度即有CppSQLite3Statement stmt;CString strSqlInsert;strSqlInsert.Format(_T("INSERT INTO %s values(1, ?)"), TABLENAME);// 将缓冲区绑定  并存到SQLite的BLOB类型中stmt = g_db.compileStatement(strSqlInsert);stmt.bind(1, pbytBuffer, nFileSize);stmt.execDML();stmt.finalize();

三、从sqlite3中读取二进制数据 并将其保存为jpg文件

C++
// 读取文件的时候用到一个函数CppSQLite3Statement::execQuery(void)
// 不知什么原因    这个函数只有声明而没有实现   
//个人能力有限   不会给其实现   所以就用的sqlite3的api// 打开数据库sqlite3 *db;if( SQLITE_OK != sqlite3_open("test1.db", &db) ){if(IDOK == ::AfxMessageBox(_T("db open error!")))return;}// 读二进制数据时要用的变量sqlite3_stmt  *pStmt;	CString strSqlSelect;// 准备pStmtsqlite3_prepare( db, "select * from tb1 where ID=1;", -1, &pStmt, 0 );sqlite3_step(pStmt);// 获取BLOB字段存放内容的长度  第二个参数是左起从0开始的位置ULONG ulImageSize = sqlite3_column_bytes(pStmt, 1);/*该函数返回指定行的第'1'列的长度   第二个参数是列的标号   从左边开始   计数从0开始  所建表共2列   第一列为ID(integer)  第二列为image(BLOB) 所以应为'1'*/char *pBufferDst = new char[ulImageSize];memset(pBuffer, 0, ulImageSize);// 将缓冲区置零// 用pBuffer接收 sqlite中存放的BLOB类型的数据返回的缓冲区指针char *pBuffer = (char *)sqlite3_column_blob(pStmt,1);/*该函数返回指定行的第'1'列的内容的缓冲区的指针   第二个参数介绍同上的sqlite3_column_bytes().*/// 将返回的缓冲区的内容拷贝到自己定义的缓冲区pBufferDst中memcpy(pBufferDst, pBuffer, ulImageSize);// 到这   sqlite3的相关资源就可以释放了sqlite3_finalize(pStmt);sqlite3_close(db);// 将缓冲区内保存的二进制数据保存到 jpg文件中CFile file;file.Open(_T("C:\\222.jpg"), CFile::typeBinary | CFile::modeWrite | CFile::modeCreate);file.Write(pBufferDst, ulImageSize);// 释放申请的堆内存资源delete[] pBufferDst;pbytBuffer = NULL;// 关闭文件file.Close();

四、最后在提供不用CppSQLite3U封装类的存储方式 – 简写了

C++// sqlite3 api 实现sqlite3 * db;int result;char buf[64];char *errmsg;errmsg = buf;// 打开数据库result = sqlite3_open("test.db", &db );// SQL语句char *sql = "CREATE TABLE tb(ID INTEGER, binData BLOB);";result = sqlite3_exec( db, sql, NULL, NULL, &errmsg);if(result != SQLITE_OK){printf("Error : %s\n", errmsg);}// 写二进制数据时要用的结构sqlite3_stmt  *stmt;// 准备插入数据sqlite3_prepare( db, "insert into tb( ID,  binData) values( 20, ? );", -1, &stmt, 0 );// 把内容和字段绑定// 执行result=sqlite3_step( stmt );sqlite3_step( stmt );// 释放相关资源sqlite3_finalize( stmt );sqlite3_close( db );

*注:本人超级菜鸟 此博客是为了总结用 仅仅说明了函数作用 可能直接编译不过 见谅 文中有何不妥之处 还望各位读者不吝赐教

这篇关于C++使用SQLite3心得 -- sqlite3以二进制形式存取图片(MFC,CppSQLite3U封装类)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1102133

相关文章

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

C#中lock关键字的使用小结

《C#中lock关键字的使用小结》在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时,其他线程无法访问同一实例的该代码块,下面就来介绍一下lock关键字的使用... 目录使用方式工作原理注意事项示例代码为什么不能lock值类型在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时

MySQL 强制使用特定索引的操作

《MySQL强制使用特定索引的操作》MySQL可通过FORCEINDEX、USEINDEX等语法强制查询使用特定索引,但优化器可能不采纳,需结合EXPLAIN分析执行计划,避免性能下降,注意版本差异... 目录1. 使用FORCE INDEX语法2. 使用USE INDEX语法3. 使用IGNORE IND

C# $字符串插值的使用

《C#$字符串插值的使用》本文介绍了C#中的字符串插值功能,详细介绍了使用$符号的实现方式,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录$ 字符使用方式创建内插字符串包含不同的数据类型控制内插表达式的格式控制内插表达式的对齐方式内插表达式中使用转义序列内插表达式中使用

flask库中sessions.py的使用小结

《flask库中sessions.py的使用小结》在Flask中Session是一种用于在不同请求之间存储用户数据的机制,Session默认是基于客户端Cookie的,但数据会经过加密签名,防止篡改,... 目录1. Flask Session 的基本使用(1) 启用 Session(2) 存储和读取 Se

Java Thread中join方法使用举例详解

《JavaThread中join方法使用举例详解》JavaThread中join()方法主要是让调用改方法的thread完成run方法里面的东西后,在执行join()方法后面的代码,这篇文章主要介绍... 目录前言1.join()方法的定义和作用2.join()方法的三个重载版本3.join()方法的工作原

Spring AI使用tool Calling和MCP的示例详解

《SpringAI使用toolCalling和MCP的示例详解》SpringAI1.0.0.M6引入ToolCalling与MCP协议,提升AI与工具交互的扩展性与标准化,支持信息检索、行动执行等... 目录深入探索 Spring AI聊天接口示例Function CallingMCPSTDIOSSE结束语

Linux系统之lvcreate命令使用解读

《Linux系统之lvcreate命令使用解读》lvcreate是LVM中创建逻辑卷的核心命令,支持线性、条带化、RAID、镜像、快照、瘦池和缓存池等多种类型,实现灵活存储资源管理,需注意空间分配、R... 目录lvcreate命令详解一、命令概述二、语法格式三、核心功能四、选项详解五、使用示例1. 创建逻