当前位置: 首页 > news >正文

Windows Mobile下访问Sqlite的Native C++封装

qlite几乎成立移动设备开发领域数据存储方面的事实标准。Sqlite已经广泛被使用到Andriod,iPhone,WebOS以及Symbian等平台了,本文讲述在Windows Mobile平台下如何使用Native C++访问Sqlite,同时讲述一个封装类的实现和使用。

Sqlite源码

Sqlite源码可以到 SQLite Download Page 下载,我为了省事直接使用了sqlite.phxsoftware.com的在Windows Mobile下的build工程。

Sqlite的C++封装

封装我使用了Tyushkov Nikolay的封装CppSQLite3U。这里感谢egmkang的推荐。CppSQLite3U封装是对Sqlite原有纯C的api进行OO的C++的封装。主要封装以下几个类:

1. CppSQLite3DB 数据库类,用于新建数据库,打开关闭链接,执行DDL和DML。

2. CppSQLite3Statement 用于执行参数化的SQL。CppSQLite3DB 可以执行SQL但是不支持参数化。

3. CppSQLite3Query 用于读出执行Select后的查询结果。

4. CppSQLite3Exception 用于捕捉异常。

简单明了的封装了Sqlite。

封装类的使用

使用方法源自于我对CppSQLite3U类的单元测试。见源文件的SqliteHelperTest.h。

创建数据库文件

TEST(SqliteHelper, CreateDatabase) { try { CppSQLite3DB db; DeleteFile(DB_FILE_NAME); db.open(DB_FILE_NAME); db.close(); } catch(CppSQLite3Exception e) { FAIL(ToString(e.errorMessage()).c_str()); } TRACE("Create database successful."); }

调用CppSQLite3DB 的open()函数的时候如果发现没有数据库文件就会新建一个数据库文件。Sqlite的源代码如下(见sqlite3.c):

rc = openDatabase(zFilename8, ppDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);

执行DDL

TEST(SqliteHelper, CreateTable) { try { CppSQLite3DB db; db.open(DB_FILE_NAME); db.execDML(L"create table T1(F1 int, F2 char(20), F3 char(20));"); db.close(); } catch(CppSQLite3Exception e) { FAIL(ToString(e.errorMessage()).c_str()); } TRACE("Create table successful."); }

执行CppSQLite3DB 的execDML()函数可以执行DDL。Sqlite3的数据类型定义和其他常见关系型数据库有很大区别,Sqlite3数据类型定义信息是和具体的数据绑定的而不是和字段定义绑定,也就是动态的,同一个字段的不同记录可以存储不同的数据类型的数据。所以在定义表的时候定义字段类型不是必须的,具体可以参考 Datatypes In SQLite Version 3。

执行DML

TEST(SqliteHelper, InsertTable) { try { CppSQLite3DB db; db.open(DB_FILE_NAME); CString sqlStr; time_t tmStart, tmEnd; tmStart = time(0); for(int i=0; i<max; ++i) { SYSTEMTIME currentTime; GetLocalTime(&currentTime); sqlStr.Format(L"INSERT INTO T1 (F1, F2, F3) VALUES(%d, 'STR%d', '%d-%d-%d %d:%d:%d')", i, i, currentTime.wYear, currentTime.wMonth, currentTime.wDay, currentTime.wHour, currentTime.wMinute, currentTime.wSecond); db.execDML(sqlStr); } tmEnd = time(0); char ch[255]; sprintf(ch, "Insert table successful in %d seconds", tmEnd-tmStart); TRACE(ch); db.close(); } catch(CppSQLite3Exception e) { FAIL(ToString(e.errorMessage()).c_str()); } }

CppSQLite3DB 的execDML()函数不仅可以执行DDL,而且可以执行DML。同理Update和Delete语句一样。

执行Scalar

TEST(SqliteHelper, SelectScalarBeforeInsert) { try { CppSQLite3DB db; db.open(DB_FILE_NAME); int count = db.execScalar(L"SELECT COUNT(*) FROM T1;"); char ch[255]; sprintf(ch, "%d rows in T1 table", count); TRACE(ch); db.close(); } catch(CppSQLite3Exception e) { FAIL(ToString(e.errorMessage()).c_str()); } TRACE("Select scalar before insert successful."); }

CppSQLite3DB 的execScalar()函数模仿ADO.NET的SqlCommand.ExecuteScalar 用于取第一条记录的一个字段的值,一般用于聚集函数的查询。

执行查询

TEST(SqliteHelper, SelectAfterInsert) { try { CppSQLite3DB db; db.open(DB_FILE_NAME); CppSQLite3Query q = db.execQuery(L"SELECT * FROM T1;"); std::string str; char ch[255]; while (!q.eof()) { sprintf(ch, "F1=%d, F2=%S, F3=%S\n", q.getIntField(0), q.getStringField(1), q.getStringField(2)); str += ch; q.nextRow(); } TRACE(str.c_str()); db.close(); } catch(CppSQLite3Exception e) { FAIL(ToString(e.errorMessage()).c_str()); } }

查询需要借助CppSQLite3Query 来取出查询的结果。eof()函数判断是否结束。nextRow()移动到下一条记录。getIntField()函数和getStringField()函数为读取当前记录的特定字段的值。

使用事务

TEST(SqliteHelper, InsertTableWithTransaction) { try { CppSQLite3DB db; db.open(DB_FILE_NAME); CString sqlStr; time_t tmStart, tmEnd; tmStart = time(0); db.execDML(L"begin transaction;"); for(int i=0; i<max; ++i) { SYSTEMTIME currentTime; GetLocalTime(&currentTime); sqlStr.Format(L"INSERT INTO T1 (F1, F2, F3) VALUES(%d, 'STR%d', '%d-%d-%d %d:%d:%d')", i, i, currentTime.wYear, currentTime.wMonth, currentTime.wDay, currentTime.wHour, currentTime.wMinute, currentTime.wSecond); db.execDML(sqlStr); } db.execDML(L"commit transaction;"); tmEnd = time(0); char ch[255];
http://www.cnnetsun.cn/news/3175310.html

相关文章:

  • Unity URP卡通渲染着色器:从原理到实践的完整指南
  • 3步掌握AMD Ryzen SDT调试工具:专业级CPU性能调优完整指南
  • NHibernate Issues之1904/1905:相同属性的Domain与Join查询/子查询
  • 智能办公本X2:端侧AI驱动的手写语音协同工作流
  • 大语言模型解码策略与低资源部署技术详解
  • NHibernate实例分享:Northwind Mapping
  • 2026年全铜卫浴五金洁具厂商口碑情况汇总
  • Vben精讲:06-Vben环境变量配置
  • MoeKoe Music终极指南:如何用开源免费客户端享受VIP音乐体验
  • Python自动化测试·Selenium操控元素的方法
  • 从Qwen-AgentWorld看大模型智能体如何操作真实系统:架构、挑战与工程实践
  • Cline 配置 Claude Sonnet 5 实战指南:思考深度调优与切换 Fable 5 的时机
  • 恶劣天气数据集 极端天气数据集 雨天道路数据集 雾天道路数据集 雪天马路恶劣环境图像目标检测数据集-道路障碍物识别数据集-数据集第10119期
  • 三千米浮空飞艇视频接入,广域立体视频孪生全域侦监技术解读 野外复杂地形动态重建 · 演训场景视频孪生目标三维重构完整体系
  • 毕业生必备7款AI写作辅助网站,一站式搞定选题初稿与降AI率
  • GHelper:华硕笔记本开源高效控制工具的专业替代方案
  • 成都茶台定制推荐
  • YOLOv10模型改进-Neck改进-第74篇:YOLOv10改进策略【Neck】| FPN-DCN可变形卷积
  • 连锁超市收银系统选什么?千店实测与商拓深度测评
  • 【湍流】基于matlab对涡粘性和雷诺应力模型FVM实现湍流通道流【含Matlab源码 15687期】含报告
  • 如何选择合适的面试机构?
  • 一文吃透 Transformers 模型加载:from_pretrained 参数大全与推理全流程解析
  • 磁吸易装 + 稳定传输,打造高效机房 U 位资产管理方案
  • 像素地理锚定标准化模型 Pixel2Geo引擎构建视频孪生空间基准体系 虚实双向指令交互通道 视频孪生联动前端感知设备智能处置技术详解
  • PPO强化学习
  • 嵌入式系统调度算法介绍
  • 【Python环境】从零解读PyCharm项目结构:虚拟环境、外部库与uv包管理器
  • 大模型微调实战:从LoRA原理到Qwen2-7B金融问答模型部署
  • 直方图靠右曝光
  • AI大模型学习指南:从Transformer到RAG与LoRA的体系化入门