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

发布时间:2026/7/6 3:49:42

Windows Mobile下访问Sqlite的Native C++封装 qlite几乎成立移动设备开发领域数据存储方面的事实标准。Sqlite已经广泛被使用到AndriodiPhoneWebOS以及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);执行DDLTEST(SqliteHelper, CreateTable) { try { CppSQLite3DB db; db.open(DB_FILE_NAME); db.execDML(Lcreate 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。执行DMLTEST(SqliteHelper, InsertTable) { try { CppSQLite3DB db; db.open(DB_FILE_NAME); CString sqlStr; time_t tmStart, tmEnd; tmStart time(0); for(int i0; imax; i) { SYSTEMTIME currentTime; GetLocalTime(currentTime); sqlStr.Format(LINSERT 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语句一样。执行ScalarTEST(SqliteHelper, SelectScalarBeforeInsert) { try { CppSQLite3DB db; db.open(DB_FILE_NAME); int count db.execScalar(LSELECT 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(LSELECT * 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(Lbegin transaction;); for(int i0; imax; i) { SYSTEMTIME currentTime; GetLocalTime(currentTime); sqlStr.Format(LINSERT 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(Lcommit transaction;); tmEnd time(0); char ch[255];

相关新闻