news 2026/7/6 3:49:20

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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];
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/6 3:49:01

Unity URP卡通渲染着色器:从原理到实践的完整指南

Unity URP卡通渲染着色器&#xff1a;从原理到实践的完整指南 【免费下载链接】UnityURPToonLitShaderExample A very simple toon lit shader example, for you to learn writing custom lit shader in Unity URP 项目地址: https://gitcode.com/gh_mirrors/un/UnityURPToon…

作者头像 李华
网站建设 2026/7/6 3:48:49

3步掌握AMD Ryzen SDT调试工具:专业级CPU性能调优完整指南

3步掌握AMD Ryzen SDT调试工具&#xff1a;专业级CPU性能调优完整指南 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https:…

作者头像 李华
网站建设 2026/7/6 3:48:31

NHibernate Issues之1904/1905:相同属性的Domain与Join查询/子查询

概览 这个系列是以博客形式整理关于NHibernate的Issues。记录一些零碎的小例子&#xff0c;通过零零碎碎的整理&#xff0c;可以巩固自己的知识和扩展我们的知识面。这些小例子也可以适当的在项目中呈现。 在接下来的NHibernate2.1.1GA版本中&#xff0c;修正了两个BUG。分别…

作者头像 李华
网站建设 2026/7/6 3:47:06

智能办公本X2:端侧AI驱动的手写语音协同工作流

1. 项目概述&#xff1a;这台办公本不是“电子纸”&#xff0c;而是你会议桌旁的沉默合伙人“如何评价科大讯飞推出的智能办公本X2&#xff1f;”——这个问题最近在律师、高校教师、咨询顾问和自由撰稿人圈子里被反复提起。我拿到真机实测三个月&#xff0c;从律所开庭前的案情…

作者头像 李华
网站建设 2026/7/6 3:47:03

大语言模型解码策略与低资源部署技术详解

自回归解码的核心流程 解码过程本质上是基于概率的序列生成。模型根据当前上下文逐个预测下一个词元&#xff0c;直到生成结束符或达到长度限制。算法2清晰展示了这一流程&#xff1a;每次迭代中模型输出概率分布P&#xff0c;通过解码策略选择下一个词元u&#xff0c;并更新上…

作者头像 李华
网站建设 2026/7/6 3:44:12

NHibernate实例分享:Northwind Mapping

本节内容 说明代码参考资料 说明 NHibernate的强大之处在于其映射&#xff0c;我们在设计Domain中&#xff0c;经常为各种各样的映射感到头痛&#xff0c;为此我把微软SQL Server2000自带的Northwind数据库使用NHibernate映射了一下&#xff0c;需要的请下载其代码&#xff…

作者头像 李华