提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
原创|其它|编辑:郝浩|2009-10-19 10:21:38.000|阅读 893 次
概述:当前移动设备开发领域,在本地数据存储方面,Sqlite几乎成了事实标准,Andriod (android.database.sqlite),iPhone (SQLite for iPhone SDK 和 FMDB for iPhone),Palm WebOS (webOS SQL Tutorial),新版本的Symbian也直接built-in Sqlite了(20 million Symbian smartphones shipped in Q3 2007 Newer versions of the SymbianOS have SQLite built in.)。那么作为移动设备领域的重要一员Windows Mobile怎么可能错过Sqlite呢。
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
当前移动设备开发领域,在本地数据存储方面,Sqlite几乎成了事实标准,Andriod (),iPhone ( 和 ),Palm WebOS (),新版本的Symbian也直接built-in Sqlite了()。那么作为移动设备领域的重要一员Windows Mobile怎么可能错过Sqlite呢。
Sqlite几乎成立移动设备开发领域数据存储方面的事实标准。Sqlite已经广泛被使用到Andriod,iPhone,WebOS以及Symbian等平台了,本文讲述在Windows Mobile平台下如何使用Native C++访问Sqlite,同时讲述一个封装类的实现和使用。
Sqlite源码可以到 下载,我为了省事直接使用了的在Windows Mobile下的build工程。
封装我使用了的封装。这里感谢的推荐。封装是对Sqlite原有纯C的api进行OO的C++的封装。主要封装以下几个类:
1. CppSQLite3DB 数据库类,用于新建数据库,打开关闭链接,执行DDL和DML。
2. CppSQLite3Statement 用于执行参数化的SQL。CppSQLite3DB 可以执行SQL但是不支持参数化。
3. CppSQLite3Query 用于读出执行Select后的查询结果。
4. CppSQLite3Exception 用于捕捉异常。
简单明了的封装了Sqlite。
使用方法源自于我对类的单元测试。见源文件的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);
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数据类型定义信息是和具体的数据绑定的而不是和字段定义绑定,也就是动态的,同一个字段的不同记录可以存储不同的数据类型的数据。所以在定义表的时候定义字段类型不是必须的,具体可以参考 。
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(¤tTime);
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语句一样。
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的 用于取第一条记录的一个字段的值,一般用于聚集函数的查询。
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(¤tTime);
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];
sprintf(ch, "Insert table successful in %d seconds", tmEnd-tmStart);
TRACE(ch);
db.close();
}
catch(CppSQLite3Exception e)
{
db.execDML(L"rollback transaction;");
FAIL(ToString(e.errorMessage()).c_str());
}
}
在Sqlite上事务的使用非常简单。通过CppSQLite3DB 的execDML()函数来打开,提交和回退事务。Sqlite在事务处理上,语法层面上和MS SQL Server有点类似,默认是自动事务(AutoCommit),关于事务处理我之前写过一篇文章,有兴趣可以参考下 。也可以参考
。 从测试结果看,批量处理数据,显式使用事务和自动事务在处理时间上差别很大。
在insert 100条数据时,显式使用事务小于1秒钟完成,而使用自动事务的话需要4秒钟。为什么有这么大的差别,我没有仔细研究Sqlite的源码,我从通用数据库的概念来讲述,事务其中一个特性是持久性(Durability),也就是凡是提交了的事务的数据都需要持久化,需要持久化就需要写硬盘,在移动设备是flash,写永久存储设备的速度是远远慢于写内存的速度的,所以速度差异点在IO。
项目开发中使用了TDD,关于Unit Test可以参考 和 。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn
文章转载自:博客园面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@pclwef.cn
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢