基于Windows CE的EDB数据库开发及应用
2015-03-23胡兆峰史高扬
胡兆峰,史高扬
(西安电子科技大学电子信息攻防对抗与仿真重点实验室,陕西西安 710071)
在编程过程中,数据库毫无疑问是一个不可忽视的部分,数据库可以完成对数据的存储和检索,可以方便人们的工作,提高工作效率。然而,因为嵌入式智能设备的资源有限,对数据库的使用有较大限制。在Windows CE操作系统中,提供了一套自带的数据库。该数据库具有数据结构简单,操作灵活等特性,在存储数量较小的情况下可以方便使用[1]。
Windows CE操作系统专门供掌上电脑和嵌入式设备使用的系统环境。Windows CE被设计成针对小型设备的通用操作系统。与其它的微软Windows操作系统不同,Windows CE并不代表一个采用相同标准对所有平台都适用的软件。为了足够灵活以适应广泛产品,Windows CE可采用不同的标准模式,即它能从一系列软件模式中做出选择,从而使产品得到定制。通过选择,Windows CE能达到系统要求的最小模式,从而减少存储脚本和操作系统的运行。
从Windows CE 5.0开始,Windows CE自带数据库系统就包括了 EDB和 CEDB,CEDB是 Windows CE 5.0之前就支持的数据库系统,EDB是 Windows CE5.0之后新增的数据库系统,EDB可以理解成对CEDB的升级。EDB是一个基于SQL Server CE的嵌入式数据库引擎,为基于Windows CE的应用程序提供核心功能,通过使用EDB,开发者能够创建一个对象存储,成为数据库卷,其中可以包含多个数据库,该数据库卷是基于文件的,因此可以被复制和移动[2]。
1 B数据库基本操作
在Windows CE系统中,学生信息存储的数据都是以EDB形式存储的。本文结合学生信息管理系统的实例介绍了EDB数据库的设计与应用开发。建立一个EDB数据库的基本思路是:首先加载数据库卷,然后在加载的数据库卷中建立数据库,数据库建立好后再打开数据库以对数据库进行读写等操作[3]。
1.1 装配数据卷
建立数据库之前应加载数据库卷,可以使用CeMountDBVol函数来实现,其函数定义如下:
BOOL CeMountDBVolEx(PCEGUID pGuid,LPWSTR lpwszDBVol,CEVOLUMEOPTIONS*poptions,DWORD dwFlags);
参数pGuid用来标识数据库文件的GUID,参数lpwszDBVol表示装备数据库卷的文件名称,参数poptions设置新数据库卷的行为和性能。如果此数据库卷已经被建立,此参数将被忽略参数poptions值为NULL,系统将设置默认的数据库卷行为和性能,参数dwFlag表示数据库卷被装载的方式。
1.2 创建数据库
加载数据库卷后,应该穿件数据库,此时可以用CeCreateDatabaseEx来创建数据库,定义如下:
CEOID CeCreateDatabaseWithProps(PCEGUID pGuid,CEDBASEINFOEX*pInfo,
DWORD cProps,CEPROPSPEC*prgProps);
参数pGuid指向已装配的数据库卷标识,参数pInfo指向CEDBASEINFOEX结构指针,用来藐视被创建的数据库的名称、类型、排序方式以及数据库特征等信息。
1.3 对数据库进行读写删除操作
在数据库建立好之后,需要对数据库进行操作,如添加记录,删除记录,修改记录,查找记录。实现以上操作的方法定义如下:
(1)读取记录。
CEOID CEReadRecordPropsEx(HANDLE hDatabase,DWORD dwFlags,LPWORD lpcPropID,CEPROPID*prgPropID,LPBYTE lplpbuffer,LPDWORD lpcbBuffer,HANDLE hHeap);
参数dwFlags为读取标识,参数lpcPropID表示参数rgPropID指向CEPROPID结构的数量。参数lplp-Buffer表示缓冲区,用于存储读取到的记录信息。
(2)写记录。
CEOID CeWriteRocordProps(HANDLE hDatabase,CEOID oidRecord,WORD cPropsID,CEPROPVAL*prg-PropVal);
参数oidRecord表示要写入记录的标识,如果参数是0,表示添加一条新纪录,否则表示要更改记录。参数cPropID表示要写入记录的字段个数,参数prgProp-Val表示要写入记录的结构体。
(3)删除记录。
BOOL CeDeleteRecord(HANDLE hDatabase,CEOID oidRecord);
参数 hDatabase表示要删除的数据库句柄,oidRecord表示要删除的记录ID。
2 开发实例
在对EDB进行操作前需要先定义一个宏,即#define EDB,将其加载开发工程中的stdafx文件中,否则将无法使用EDB相关的函数。具体数据库的创建思路与上文相同,本数据库共由5个字段构成,分别是学生姓名,学号,性别,联系电话,照片。
2.1 打开学生信息数据库
首先加载Windows CE系统学生信息数据库所在的卷文件“\student.vol”,然后再打开数据库,本数据库有两个排序字段,分别是姓名和学号,这样在搜索数据库时可以利用EDB自带的API函数对这两个字段的类内容进行搜索。
2.2 记录的读取
通过对EDB数据库进行分析,可以得到各个属性的PropID,从而对学生信息进行读取。核心代码如下:
/* -------------------
【函数介绍】:读取记录;根据学生编号,修改记录
【入口参数】:strNo:学生编号
pRecStudent:学生数据库表结构
【出口参数】:(无)
【返回值】:TRUE:编辑成功;FALSE:编辑失败
-------------------*/
ceOid=CeSeekDatabaseEx(tblStudent.m_hDB,CEDB_SEEK_VALUEFIRSTEQUAL,(DWORD)&seekPropVal,1,&dwIndex);
if(ceOid==0)
{TRACE(L"未查找到此记录 ");
goto error;}
//写入记录
tmpCeOid=CeWriteRecordProps(tblStudent.m_hDB,ceOid,4,pProps);
if(tmpCeOid==0){
TRACE(L"写入记录失败 ");
goto error;}
2.3 删除添加记录
如果要从数据库中删除一个学生信息,只需要换的该学生信息的CEOID,然后通过调用CEDeleteRecord函数删除。
ceOid=CeSeekDatabaseEx(tblStudent.m_hDB,CEDB_SEEK_VALUEFIRSTEQUAL,(DWORD)&seekPropVal,1,&dwIndex);
if(ceOid==0)
{TRACE(L"未查找到此记录 ");
goto error;
}
//删除当前记录
if(!CeDeleteRecord(tblStudent.m_hDB,ceOid))
{TRACE(L"删除记录失败 ");
goto error;
}
向数据库添加一个学生信息,需要先填充属性结构CEPROPVAL,然后调用 CEWriteRecordProps添加。该函数也可以用于修改某个已经存在的记录属性值。
//首先填充CEPROPVAL属性结构
CEPROPVAL pProps[4];
DWORD dwErrorCode=0;
DWORD dwWritten=0;
//定义内存流句柄,用于写入照片数据
HANDLE hStream=INVALID_HANDLE_VALUE;
//1,打开学生数据库
if(!tblStudent.DB_Open_Student())
{
//打开学生数据库失败
return FALSE;
}
//给字段属性赋值
ZeroMemory(&pProps[0],sizeof(CEPROPVAL)*4);
//学生学号
pProps[0].propid=PID_NO;
pProps[0].val.lpwstr=LPWSTR(pRecStudent→szNo);
pProps[0].wFlags=0;
……
//写入记录
ceOid=CeWriteRecordProps(tblStudent.m_hDB,0,4,pProps);
if(ceOid==0)
{
dwErrorCode=GetLastError();
//如果 dwErrorCode=183,表示学生编号重复
if(dwErrorCode==ERROR_ALREADY_EXISTS)
{
TRACE(L"学生编号重复 ");
}
else
{
TRACE(L"写入记录失败,Error Code=%d ",dwErrorCode);
}
goto error;
}
2.4 查找记录
EDB数据库支持多种查找方式,比如指定位置查找,指定条件查找等,数据库记录的查找,通过CeSeek-DatabaseEx实现。CESeekDatabaseEx函数的 dwSeek-Type参数指定查找方式,常用的几种查找方式如下:
直接查找指定位置的记录(CEDB_SEEK_CEOID);
从开始位置查找(CEDB_SEEK_BEGINNING);
从最后位置查找(CEDB_SEEK_END);
从当前位置查找(CEDB_SEEK_CURRENT);
查找第一条属性等于指定值的记录(CEDB_SEEK_VALUEFIRSTEQUAL);
查找下一条属性等于指定值的记录(CEDB_SEEK_VALUESMALLER);
查找小于等于指定属性值的记录(CEDB_SEEK_VALUESMALLEROREQUAL);
查找大于指定属性值的记录(CEDB_SEEK_VALUEGREATER);
查找大于或者等于指定属性值的记录(CEDB_SEEK_VALUEGREATEROREQUAL)[4]。
3 结束语
开发数据库的是一个复杂的过程,只有掌握较多的知识才可以开发出功能强大,性能稳定的数据库。在数据库开发过程中,通常会存在多个结构体嵌套的情况,因而涉及到很多的结构体和指针变量,在开发中要特别注意指针和内存的问题,要防止内存泄露,指针要及时清空。
[1]汪兵.Windows CE嵌入式高级编程及其实例详解[M].北京:中国水利水电出版社,2008.
[2]田东风.Windows CE应用程序设计[M].北京:机械工程出版社,2005.
[3]Microsoft.Microsoft MSDN mobile专区[EB/OL](2006 -07-18)[2013 -05 -16]http;//msdn.microsoft.com/en- us/windowsmobile/default.apsx,2006.
[4]沈建国.Windows CE 5.0 EDB数据库的应用与开发[D].重庆:重庆邮电大学,2007.
[5]杜春雷.ARM体系结构与编程[M].北京:清华大学出版社,2008.