APP下载

SQLite移动嵌入式数据库BLOB类型的应用

2014-07-09刘玉海

移动通信 2014年6期
关键词:数据类型二进制语句

在对移动嵌入式数据库中BLOB数据类型分析的基础上,使用C语言的API函数调用移动SQLite数据库语句,并按其访问模式调用连接函数,实现了SQLite移动数据库中二进制大对象和C结构体类型数组的BLOB处理方法。随着图像和音视频数据的日益增多,BLOB数据类型在SQLite中的应用将更为广阔,给出的Demo实例验证了这一技术的有效性。

SQLite移动数据库 BLOB类型 嵌入式开发

中图分类号:TP311 文献标识码:A 文章编号:1006-1010(2014)-06-

1 引言

移动嵌入式数据库一直是一个热点应用开发,作为轻量级嵌入式移动数据库的典型,SQLite有许多令人印象深刻的优点,包括:具有开放源代码;自身程序特别小;支持大多数SQL命令;速度极快;直接创建数据库,不需要服务器支持;简洁的C语言API(Application Programming Interface,应用程序编程接口)接口。它具有的零配置安装可在系统崩溃或电源故障时自动恢复,且数据被存储在单一的物理文件中,数据库运行在同一个相互间无通信的进程,访问数据库的程序直接从文件读取和写入磁盘,数据的读写速度快,具有高达2TB的存储容量,在提供了存储BLOB(Binary Large Object,二进制大对象)方法的同时,API扩展等也提供了强有力的技术支撑;存储在SQLite数据库BLOB数据类型的输入数据无需任何转换,数据本身的属性就是表的列属性[1]。

2 BLOB技术原理

BLOB数据类型是适合用于存储可变长度的二进制大对象数据以及可变长度的音频和视频数据。在SQLite的BLOB类型中存储复杂的数据时,长度是不加限制的[2]。使用B-树索引来管理和组织属性数据,通过SQL语句到数据库相关数据中实现增、删、改、查的操作。SQLite不支持静态数据类型,而是使用列关系。当数据记录的字段内容插入到数据库中时,SQLite将对该字段内容的类型做检查,若类型不能匹配到相关联的列,则SQLite会将该字段内容转换成列的类型。因此,数据库中BLOB数据类型的合理应用也直接影响存储效率和查询速度的提高。

3 BLOB类型在SQLite中的应用

3.1 SQLite的API函数

嵌入式移动数据库SQLite使用C语言API等接口,在此基础上的扩展也可用于其他语言的SQLite的接口[3]。以下是SQLite中常用的对数据库进行操作的函数:

(1)创建和打开数据库

int sqlite3_open(const char*,sqlite3**db);

功能是当数据库文件存在时,可以打开已存在的数据库;若不存在,则创建一个新的数据库文件并打开,且能通过输入参数返回连接。

(2)运行函数

int sqlite3_exec(sqlite3*,const char*sql,sqlite_callback,void*,char**em);

*sql是运行的SQL语句,该语句可按实际需要编写一条或多条;sqlite_callback是一个回调函数,根据实际可编写回调函数从数据库中获取需要的结果。

(3)预编译SQL语句的函数

int sqlite3_prepare(sqlite3*db,const char*iSql,int jByte,sqlite3_stmt**pStmt,const char**pl);

该函数需要一个数据库连接的指针,将给定的SQL文本转换为预声明语句对象并返回一个指向它的指针,这个函数并不执行SQL语句,只是预编译和解析SQL文本,准备执行。

(4)查询函数

int sqlite3_get_table(sqlite3*,const char*sql,char ***ret,int*nrow,int*ncol,char**em);

功能是无需回调函数处理,直接能查询结果集。

3.2 SQLite数据库BLOB类型应用实例

(1)SQLite二进制大对象处理技术

在实际编程开发中,往往是进行二进制大对象数据的访问,如图像、音视频等。对于这些数据不能像对待普通的文本一样插入或查询那样简单,而是将图像等文件在使用Insert或Update语句时先用通配符‘?代替,通配符‘?表示未定值是一个占位符,然后通过sqlite3_bind_blob绑定到Insert或Update中,替换‘?部分并存储。如果是字符串,则还需要通过sqlite3_bind_parameter_index()获取对应的index,然后再调用sqlite3_bind_blob()操作。通常也用于构造不定条件的动态SQL语句。

以下的Demo1.c程序就实现了SQLite数据库中图像的存取处理[4]:

//创建表函数

int CreateTab(sqlite3*db)

{char*EM=0; //*EM指针返回错误消息

char*sql="CREATE TABLE xuch(BH primart key,MC varchar(10),SL int,SB blob); "

if(SQLITE_OK)!=sqlite3_exec(db, 0,0,&EM))

{printf(" failed:%s\n",EM);}

}

//插入数据记录并处理大对象数据函数

int InsertRec(sqlite3*db)

{……endprint

char*sql="INSERT INTO xuch(BH,MC,SL) VALUES(‘20121001,Computer,20); "

……

char*sql="UPDATE xuch SET SB=? WHERE MC='Computer';" //‘?通配符是占位符代替二进制文件

}

……//此处需应有为占位符‘?所提供的图像视频等大对象文件的打开等操作

sqlite3_bind_blob(stmt, 1, fl, fs, NULL);//调用该函数使Update中‘?代表的参数传入对应字段,其中的stmt记录了SQL语句。

如果有多个‘?,就需要写出多个sqlite3_bind_blob语句,并改变它们的第2个参数即可替换到不同的‘?。最后使用sqlite3_step将二进制数据保存到对应的数据库中。

(2)C结构体类型在BLOB中的处理技术

将一个结构体数据以二进制的方式写入到SQLite数据库的BLOB类型中,并显示出结果。

Demo2.c程序主要代码如下所示,其中personal是一个结构体数组。

sqlite3*db;

sqlite3_open("test.db", &db);

sqlite3_stmt*stmt;

typedef struct xuchunhua

{ int no;

char name[10];

bool sex;

}teacher;

teacher personal[20];

……

personal[1].no=10;

strcpy(personal[1].name,“LiuBing”);

personal[i].bool=1;

……

result=sqlite3_exec(db,"create table xuch(bh text,jg blob)", 0,0,&perrmsg); //创建对应的表,这里用到了blob类型

result=sqlite3_prepare(db,"insert into xuch values(?,?)",-1,&stmt,0); //插入数据,这里采用预编译的形式,凡是二进制的数据都要这样处理[5]

……

void*buffer ; //创建内存指针

buffer=new char(sizeof(teacher)); //初始化存储空间,sizeof(teacher)为结构体大小

……

result=sqlite3_bind_text(stmt,1,“X1001”, -1,NULL); //绑定表的第一个字段,这里为text类型

result=sqlite3_bind_blob(stmt,2,buffer,sizeof(teacher),NULL); //绑定blob类型

result=sqlite3_step(stmt); //执行sql语句,这样就把数据存到数据库里了

……

result=sqlite3_prepare(db,"select jg from xuch

where bh=“X1001”,-1,&stmt,0); //查找一行的数据

result=sqlite3_step(stmt);

if(result==SQLITE_ROW)

{

int blob_size=sqlite3_column_bytes(stmt,0)/sizeof(teacher); //获取数组的长度

personal1=(teacher*)sqlite3_column_blob(stmt,0); //获取数组的头指针

for(int i=0 ;i

{printf("%d",personal[i].sno);

printf("%s",personal[i].sname; //输出数据

……}

}

sqlite3_finalize(stmt);

sqlite3_close(db);

4 结束语

SQLite提供了存取二进制大对象BLOB的方法,在嵌入式移动数据库开发中,可对二进制大对象和C结构体使用BLOB类型数据处理。SQLite移动数据库的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用,它占用的资源非常低。SQLite嵌入式移动数据库的易用性,可加快应用程序的开发,完全支持复杂的SQL,对于小型设备的有限空间来说是特别重要的应用。此外,SQL还支持原子的、一致的、独立的和持久的(ACID)事务。SQLite允许多个进程同时打开一个数据库,同时读取数据库实现并发处理。随着应用的广泛,在移动数据库中具有越来越多的图像数据、大文本数据、音频和视频数据,在SQLite中BLOB数据类型的应用将更为广阔。

参考文献:

[1] Michael Owens. The Definitive Guide to SQLite[M]. Berkeley: Apress, 2006.

[2] 叶宏祥. 移动存储关键性技术的研究及进展[J]. 移动通信, 2009(11): 32-34.

[3] The Architecture of SQLite[EB/OL]. [2013-08-21]. http://www.sqlite.org/arch.html.

[4] 刘玉海,刘冰. SQLite嵌入式数据库及图象处理技术研究[J]. 软件, 2012(8): 102-104.

[5] C/C++ Interface for SQLite Version3[EB/OL]. [2013-08-21]. http://www.sqlite.org/capi3ref.html.★

char*sql="INSERT INTO xuch(BH,MC,SL) VALUES(‘20121001,Computer,20); "

……

char*sql="UPDATE xuch SET SB=? WHERE MC='Computer';" //‘?通配符是占位符代替二进制文件

}

……//此处需应有为占位符‘?所提供的图像视频等大对象文件的打开等操作

sqlite3_bind_blob(stmt, 1, fl, fs, NULL);//调用该函数使Update中‘?代表的参数传入对应字段,其中的stmt记录了SQL语句。

如果有多个‘?,就需要写出多个sqlite3_bind_blob语句,并改变它们的第2个参数即可替换到不同的‘?。最后使用sqlite3_step将二进制数据保存到对应的数据库中。

(2)C结构体类型在BLOB中的处理技术

将一个结构体数据以二进制的方式写入到SQLite数据库的BLOB类型中,并显示出结果。

Demo2.c程序主要代码如下所示,其中personal是一个结构体数组。

sqlite3*db;

sqlite3_open("test.db", &db);

sqlite3_stmt*stmt;

typedef struct xuchunhua

{ int no;

char name[10];

bool sex;

}teacher;

teacher personal[20];

……

personal[1].no=10;

strcpy(personal[1].name,“LiuBing”);

personal[i].bool=1;

……

result=sqlite3_exec(db,"create table xuch(bh text,jg blob)", 0,0,&perrmsg); //创建对应的表,这里用到了blob类型

result=sqlite3_prepare(db,"insert into xuch values(?,?)",-1,&stmt,0); //插入数据,这里采用预编译的形式,凡是二进制的数据都要这样处理[5]

……

void*buffer ; //创建内存指针

buffer=new char(sizeof(teacher)); //初始化存储空间,sizeof(teacher)为结构体大小

……

result=sqlite3_bind_text(stmt,1,“X1001”, -1,NULL); //绑定表的第一个字段,这里为text类型

result=sqlite3_bind_blob(stmt,2,buffer,sizeof(teacher),NULL); //绑定blob类型

result=sqlite3_step(stmt); //执行sql语句,这样就把数据存到数据库里了

……

result=sqlite3_prepare(db,"select jg from xuch

where bh=“X1001”,-1,&stmt,0); //查找一行的数据

result=sqlite3_step(stmt);

if(result==SQLITE_ROW)

{

int blob_size=sqlite3_column_bytes(stmt,0)/sizeof(teacher); //获取数组的长度

personal1=(teacher*)sqlite3_column_blob(stmt,0); //获取数组的头指针

for(int i=0 ;i

{printf("%d",personal[i].sno);

printf("%s",personal[i].sname; //输出数据

……}

}

sqlite3_finalize(stmt);

sqlite3_close(db);

4 结束语

SQLite提供了存取二进制大对象BLOB的方法,在嵌入式移动数据库开发中,可对二进制大对象和C结构体使用BLOB类型数据处理。SQLite移动数据库的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用,它占用的资源非常低。SQLite嵌入式移动数据库的易用性,可加快应用程序的开发,完全支持复杂的SQL,对于小型设备的有限空间来说是特别重要的应用。此外,SQL还支持原子的、一致的、独立的和持久的(ACID)事务。SQLite允许多个进程同时打开一个数据库,同时读取数据库实现并发处理。随着应用的广泛,在移动数据库中具有越来越多的图像数据、大文本数据、音频和视频数据,在SQLite中BLOB数据类型的应用将更为广阔。

参考文献:

[1] Michael Owens. The Definitive Guide to SQLite[M]. Berkeley: Apress, 2006.

[2] 叶宏祥. 移动存储关键性技术的研究及进展[J]. 移动通信, 2009(11): 32-34.

[3] The Architecture of SQLite[EB/OL]. [2013-08-21]. http://www.sqlite.org/arch.html.

[4] 刘玉海,刘冰. SQLite嵌入式数据库及图象处理技术研究[J]. 软件, 2012(8): 102-104.

[5] C/C++ Interface for SQLite Version3[EB/OL]. [2013-08-21]. http://www.sqlite.org/capi3ref.html.★

char*sql="INSERT INTO xuch(BH,MC,SL) VALUES(‘20121001,Computer,20); "

……

char*sql="UPDATE xuch SET SB=? WHERE MC='Computer';" //‘?通配符是占位符代替二进制文件

}

……//此处需应有为占位符‘?所提供的图像视频等大对象文件的打开等操作

sqlite3_bind_blob(stmt, 1, fl, fs, NULL);//调用该函数使Update中‘?代表的参数传入对应字段,其中的stmt记录了SQL语句。

如果有多个‘?,就需要写出多个sqlite3_bind_blob语句,并改变它们的第2个参数即可替换到不同的‘?。最后使用sqlite3_step将二进制数据保存到对应的数据库中。

(2)C结构体类型在BLOB中的处理技术

将一个结构体数据以二进制的方式写入到SQLite数据库的BLOB类型中,并显示出结果。

Demo2.c程序主要代码如下所示,其中personal是一个结构体数组。

sqlite3*db;

sqlite3_open("test.db", &db);

sqlite3_stmt*stmt;

typedef struct xuchunhua

{ int no;

char name[10];

bool sex;

}teacher;

teacher personal[20];

……

personal[1].no=10;

strcpy(personal[1].name,“LiuBing”);

personal[i].bool=1;

……

result=sqlite3_exec(db,"create table xuch(bh text,jg blob)", 0,0,&perrmsg); //创建对应的表,这里用到了blob类型

result=sqlite3_prepare(db,"insert into xuch values(?,?)",-1,&stmt,0); //插入数据,这里采用预编译的形式,凡是二进制的数据都要这样处理[5]

……

void*buffer ; //创建内存指针

buffer=new char(sizeof(teacher)); //初始化存储空间,sizeof(teacher)为结构体大小

……

result=sqlite3_bind_text(stmt,1,“X1001”, -1,NULL); //绑定表的第一个字段,这里为text类型

result=sqlite3_bind_blob(stmt,2,buffer,sizeof(teacher),NULL); //绑定blob类型

result=sqlite3_step(stmt); //执行sql语句,这样就把数据存到数据库里了

……

result=sqlite3_prepare(db,"select jg from xuch

where bh=“X1001”,-1,&stmt,0); //查找一行的数据

result=sqlite3_step(stmt);

if(result==SQLITE_ROW)

{

int blob_size=sqlite3_column_bytes(stmt,0)/sizeof(teacher); //获取数组的长度

personal1=(teacher*)sqlite3_column_blob(stmt,0); //获取数组的头指针

for(int i=0 ;i

{printf("%d",personal[i].sno);

printf("%s",personal[i].sname; //输出数据

……}

}

sqlite3_finalize(stmt);

sqlite3_close(db);

4 结束语

SQLite提供了存取二进制大对象BLOB的方法,在嵌入式移动数据库开发中,可对二进制大对象和C结构体使用BLOB类型数据处理。SQLite移动数据库的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用,它占用的资源非常低。SQLite嵌入式移动数据库的易用性,可加快应用程序的开发,完全支持复杂的SQL,对于小型设备的有限空间来说是特别重要的应用。此外,SQL还支持原子的、一致的、独立的和持久的(ACID)事务。SQLite允许多个进程同时打开一个数据库,同时读取数据库实现并发处理。随着应用的广泛,在移动数据库中具有越来越多的图像数据、大文本数据、音频和视频数据,在SQLite中BLOB数据类型的应用将更为广阔。

参考文献:

[1] Michael Owens. The Definitive Guide to SQLite[M]. Berkeley: Apress, 2006.

[2] 叶宏祥. 移动存储关键性技术的研究及进展[J]. 移动通信, 2009(11): 32-34.

[3] The Architecture of SQLite[EB/OL]. [2013-08-21]. http://www.sqlite.org/arch.html.

[4] 刘玉海,刘冰. SQLite嵌入式数据库及图象处理技术研究[J]. 软件, 2012(8): 102-104.

[5] C/C++ Interface for SQLite Version3[EB/OL]. [2013-08-21]. http://www.sqlite.org/capi3ref.html.★

猜你喜欢

数据类型二进制语句
用二进制解一道高中数学联赛数论题
详谈Java中的基本数据类型与引用数据类型
重点:语句衔接
如何理解数据结构中的抽象数据类型
有趣的进度
二进制在竞赛题中的应用
如何搞定语句衔接题
范畴数据类型上的子类型*
一个生成组合的新算法
作文语句实录