WINCE自带数据库系统
WINCE 提供一种简单的数据库系统,由于该数据库系统最多只能支持4种排序索引,因此使用它只能组织一些简单的数据库,如通讯簿,邮件等。 在较老的WINCE版本中,数据库只能驻留在对象存储库中,而不能存储在外部介质中。从WINCE2.1版本之后,通过引入卷的概念后,就可以将数据库存储在外部介质中了。
l 何为数据库卷?
数据库卷是可以存储WINCE数据库的特殊格式的文件。在WINCE中,如果想把数据库存储在文件中或则需要随意拷贝或删除数据库文件,就需要使用数据库卷。
与数据库卷对应的是对象存储库,在WINCE2.1以前的版本中数据库都是存放在对象存储库中的,对象存储库不支持拷贝,删除。
l 到这里我觉得有必要谈谈数据库的基本的一个结构,让我们来看看一张具体的图片我们就能了解到WINCE 数据库的结构了。这里我们主要谈到的是字段和记录!
就这张图而言,Title和Rating 就是字段,而每一行就是一条记录。在WINCE 中字段的类型有九种:
数据类型 | 说明 | 对应常量 |
iVal | 两个字节的有符号整数 | CEVT_I2 |
uiVal | 两个字节的无符号整数 | CEVT_UI2 |
lVal | 4个字节有符号整数 | CEVT_I4 |
ulVal | 4个字节的无符号整数 | CEVT_UI4 |
filetime | 日期时间结构 | CEVT_FILETIME |
lpwstr | 以0 结束的Unicode字符串 | CEVT_LPWSTR |
blob | CEBLOB结构,这里可以用来存储大对象,例如图片或声音文件等 | CEVT_BLOB |
BoolVal | 布尔值 | CEVT_BOOL |
dblVal | 8 个字节的有符号值 | CEVT_R8 |
这些字段在你设计自己的数据库时会有帮助。
l 数据库的操作流程:
1步:装配数据库卷(如果针对对象存储库,该步骤可以省略)
BOOL CeMountDBVol(
PCEGUID pceguid, //数据库卷的标识
LPWSTR lpszDBVol,//数据库文件的路径
DWORD dwFlags);//表示数据库卷被装载的方式(dwFlags的具体的使用请查看MSDN )
2步:打开数据库(如果不存在就创建一个需要的数据库)
针对对象存储库中的数据库
HANDLE CeOpenDatabase(
PCEOID poid, //要被打开的数据库ID 如果使用数据库名称打开数据库,应该将poid设置成0
LPWSTR lpszName ,//要被打开的数据库名称,如果参数poid设置非0,那么该参数被忽略
CEPROPID propid,//制定打开时使用那种次序来排序数据库
DWORD dwFlags,//取值0或CEDB_AUTOINCREMENT.如果指定的是0那么每次从数据库中读取一条记录数据库当前记录指针不会移动。如果是CEDB_AUTOINCREMENT表示读一次,当前记录指针会移动到下一条记录。
HWND hwndNotify);//表示当另一个进程或线程更改数据库时要通知的窗口句柄。
如果针对数据库卷使用
HANDLE CeOpenDatabaseEx(
PCEGUID pceguid, //已经装配的数据卷标示
PCEOID poid,
LPWSTR lpszName,
CEPROPID propid,
DWORD dwFlags,
CENOTIFYREQUEST* pReq)//数据库更改消息(关于消息的结构可以参考MSDN )
注:这里有必要提到一点的是在使用PCEOID poid这个参数时,如果你想使用数据库名称打开就必须把poid置0,但是置0 不等于可以直接把0 填上去。
例如:HANDLE CeOpenDatabaseEx( pceguid,0, lpszName,propid, dwFlags, pReq)就是一个错误的操作!
3步:通过使用CeSeekDatabase移动记录的指针。
CEOID CeSeekDatabase(
HANDLE hDatabase, //需要SEEK的数据库句柄
DWORD dwSeekType, //SEEK记录的类型
DWORD dwValue, //从第dwValue条记录开始
LPDWORD lpdwIndex);//返回索引的值
注:对空的记录是不能SEEK 的,如果使用就会造成错误
4步:执行数据的存取操作
通过CeReadRecordProps (CEDB),CeWriteRecordProps (CEDB)进行记录的读写操作,还有删除记录等操作,我这里重点介绍一下常用的两个,即读和写操作!
CEOID CeReadRecordProps(
HANDLE hDbase, //数据库句柄
DWORD dwFlags, //读取标识
LPWORD lpcPropID, //字段的数量
CEPROPID* rgPropID, //指向CEPROPID结构的数组,表示需要读取的字段,如果为空表示读取所有字段
LPBYTE* lplpBuffer, //存储记录的信息
LPDWORD lpcbBuffer);表示lplpBuffer缓冲区的大小
CEOID CeWriteRecordProps(
HANDLE hDbase,
CEOID oidRecord, //记录的ID
WORD cPropID, //需要写的字段数量
CEPROPVAL* rgPropVal);//写入的记录信息
注:在写一条新记录的时候应该把 CEOID oidRecord置0;
5步:关闭数据库的句柄,卸载卷!
注:数据操作的所有函数通过这个链接都可以找到。
l 关于数据库的枚举
//查找对象存储库中的所有数据库
hEnumDB= CeFindFirstDatabase(0);
if (hEnumDB==INVALID_HANDLE_VALUE)
{
if(GetLastError()==ERROR_OUTOFMEMORY)
wsprintf(szMsg,_T("Out of memory."));
else
wsprintf(szMsg,_T("Unknown error."));
return false;
}
while((CeOid=CeFindNextDatabase(hEnumDB))!=0)
{
//得到数据库的信息
if (!CeOidGetInfo(CeOid,&CeObjectInfo))
{
CloseHandle(hEnumDB);
return false;
}
else
{
根据自己的需要的对找的数据库进行操作;
}
如果是遍历卷中的数据库只需要把
CeFindFirstDatabase换成CeFindFirstDatabaseEx(),
CeFindNextDatabase换成CeFindNextDatabaseEx(),
再根据不同的参数要求改变一下即可!