文档简介
项目需要使用SQLite,这是一款主要用于嵌入式轻型的数据库,本文档主要目的在于记录如何使用基于QT平台的UI与SQLite进行连接,并简单介绍SQLite的使用方法。
文档分为以下几个部分:
A.SQLite的交叉编译;
B.QT连接SQLite;
C.SQLite的使用方法;
编译环境:
操作系统:Ubuntu11.04
本机平台:X86
目标平台:Loongson1B开发板
交叉编译工具链:gcc-3.4.6-2f(1B交叉编译工具链)
所需软件及工具包:
qt-embedded-free-3.3.7.tar.gz
sqlite3_3.7.4.orig.tar.gz
1.SQLite的交叉编译
首先获取SQLite的源码包,可以在sqlite的官网下载源码包:
http://www.sqlite.org/download.html
也可以在Ubuntu中使用以下命令获取sqlite的源码包:
#apt-getsourcesqlite3
下载完在当前目录下能看到多了几个文件,其中
sqlite3_3.7.4.orig.tar.gz
即为sqlite的官方源码包。
解压后进入sqlite3-3.7.4目录:
执行以下命令:
#./configure--hostmipsel-linux--prefix/mipsel-linux-sqlite3/
#make
#makeinstall
编译过程一般出现的错误都是因为缺少相关组件的库的缘故,只需要根据相关错误打印信息搜索相关组件,然后apt-get安装后再次编译即可编译通过。
编译完成后在/mipsel-linux-sqlite3/目录下能看到三个文件夹:
bin/include/lib/
分别是sqlite的可执行文件、头文件和动态库,在接下来的QT连接SQLite过程中需要用到此目录下的sqlite头文件和动态库。
2.QT连接SQLite
在现有的QT程序内使用SQLite,主要是将sqlite的头文件包含到QT功能内,并指明sqlite头文件和动态库所在目录,在编译QT应用程序时将sqlite一起编译进去即可。
下边创建一个sqlite3-test工程为例子:
#mkdirsqlite3-test
#cdsqlite3-test/
#vimain.cpp
/******main.cpp*******/ #include <qapplication.h> #include <qwidget.h> #include <qstring.h> #include <sqlite3.h> // 添加sqlite头文件 #define SQL_FILE "/data/netDev.db" //sqlite数据库文件路径 sqlite3 *db; //sqlite文件描述符 int main(int argc, char *argv[]) { QApplication app(argc, argv); db=NULL; int sqlite_error; sqlite_error = sqlite3_open(SQL_FILE, &db); //打开指定的数据库文件,如果不存在将创建一个同名的数据库文件 if( sqlite_error != SQLITE_OK ) { qDebug("sqlite_error"); } int nRow, nColumn; int i,j; int index; char **dbResult; char * errmsg = NULL; int result = sqlite3_get_table( db, "select * from netDev", &dbResult, &nRow, &nColumn, &errmsg ); //执行指定指令:"select * from netDev"其中netDev为打开的数据库文件的table名字 if( SQLITE_OK == result ) { printf( "-------\n" ); index = nColumn; printf( "Check record:%d \n", nRow ); for( i = 0; i < nRow ; i++ ) { printf( "NO. %d :\n", i+1 ); for( j = 0 ; j < nColumn; j++ ) { printf( "Name:%s > Data:%s\n", dbResult[j], dbResult [index] ); ++index; } printf( "-------\n" ); } } sqlite3_free_table( dbResult ); return app.exec(); }#visqlite3-test.pro
/******sqlite3-test.pro*******/
TEMPLATE=app
CONFIG-=moc
INCLUDEPATH+=.
#指定sqlite的头文件及动态库路径
SQLITE_PATH=/mipsel-linux-sqlite3
DEPENDPATH+=$$SQLITE_PATH/include
INCLUDEPATH+=$$SQLITE_PATH/include
LIBS+=-L$$SQLITE_PATH/lib
LIBS+=-lsqlite3
#Input
SOURCES+=main.cpp
然后使用qmake-qt3工具生成Makefile后检查Makefile文件中的LIBS是否定义了-L/mipsel-linux-sqlite3/lib-lsqlite3;以及INCPATH是否定义了-I/mipsel-linux-sqlite3/include;
再执行make进行编译,然后查看生成的二进制文件sqlite3-test所需的动态库文件,将目标板运行QT3应用程序相关文件以及自定义的sqlite数据库文件移植到目标板的文件系统中指定位置,在板上执行
#./sqlite3-test-qws
打印信息如下:
-------
Checkrecord:3
NO.1:
Name:ID>Data:NO1
Name:message>Data:chenyuxin
-------
NO.2:
Name:ID>Data:NO2
Name:message>Data:ethan
-------
NO.3:
Name:ID>Data:NO3
Name:message>Data:hello
-------
获取到三组数据,每一组有两个成员,分别是ID和message,到此已经验证QT成功连接sqlite了。
下边将介绍sqlite具体的一些使用方法。
3.SQLite的使用方法
3.1SQLite工具的使用
首先在Ubuntu中获取sqlite工具包:
#apt-getinstallsqlite3
下边介绍一些该工具相关的常用使用方法:
1、创建一个新的数据库:sqlite3name.db
先建立一个Db目录,并在Db目录中创建一个test.db数据库文件,打开控制台窗口,命令如下:
#mkdirsqlite3-test
#cdmkdirsqlite3-test
#sqlite3test.db
2、打开一个已经存在的数据库:sqlite3name.db
创建一个新数据库和打开一个已经存在的数据库命令是一模一样的,如果文件在当前目录下不存在,则新建;如果存在,则打开。
3、导入数据:.readname.sql
在sqlite3-test目录下创建一个空文件:test.sql,然后在里边写入相关的SQL语句,例如:
BEGINTRANSACTION;
CREATETABLECars(IdintegerPRIMARYKEY,Nametext,Costinteger);
INSERTINTOCarsVALUES(1,'Audi',52642);
INSERTINTOCarsVALUES(2,'Mercedes',57127);
INSERTINTOCarsVALUES(3,'Skoda',9000);
INSERTINTOCarsVALUES(4,'Volvo',29000);
INSERTINTOCarsVALUES(5,'Bentley',350000);
INSERTINTOCarsVALUES(6,'Citroen',21000);
INSERTINTOCarsVALUES(7,'Hummer',41400);
INSERTINTOCarsVALUES(8,'Volkswagen',21600);
COMMIT;
在命令行环境中输入
.readtest.sql
即将所有的数据导入到test.db数据库中
4、列出所有的数据表:.tables
完成上面所有的工作以后,我们就可以列出所有的数据表了
当前test.db内仅有一个表,表名为Cars。
5、导出某个表的数据:.dump
整个表以SQL语句的形式为导出来了,但是只是显示在终端上,如何把它导出到文件中呢?
6、设置导出目标:
.output
或者
.outputstdout
先运行.outputcars.sql,然后再运行.dump则数据保存到cars.sql文件,如果要恢复成导出到终端(标准输出),则运行.outputstdout。
7、创建表
在命令行里大部份的SQL语句它都是支持的,现在来新建一个表
sqlite>createtableArtists(
--->ArtistIDINTEGERPRIMARYKEY,
--->ArtistNameTEXT);
其中表名为Artists,有两个成员分别是ArtistID和ArtistName,后边是该成员携带的数据,INTEGER表示指定数据类型为整形;
sqlite对SQL语句大小写不敏感,所以大写小写都可以。
使用.tables查询后可知现在本数据库文件有两个表:Artists、Cars。
8、插入数据
sqlite>insertintoArtists(ArtistID,ArtistName)values(NULL,'PeterGabriel');
sqlite>insertintoArtists(ArtistID,ArtistName)values(NULL,'BruceHornsby');
sqlite>insertintoArtists(ArtistID,ArtistName)values(NULL,'LyleLovett');
sqlite>insertintoArtists(ArtistID,ArtistName)values(NULL,'BeachBoys');
9、表查询
查看指定表名的内容,若有需要,先打开表头,执行一下语句:
sqlite>.headersON
sqlite>select*fromArtists;
查询到的内容为:
ArtistID|ArtistName
1|PeterGabriel
2|BruceHornsby
3|LyleLovett
4|BeachBoys
10、更新字段
若想更新ArtistID=4的歌手名字为Santana,执行一下指令:
sqlite>UPDATEArtistsSETArtistName='Santana'WHEREArtistID=4;
然后再次查询内容变更成:
ArtistID|ArtistName
1|PeterGabriel
2|BruceHornsby
3|LyleLovett
4|Santana
11、删除字段
首先执行
sqlite>select*FROMArtistsWHEREArtistNameLIKE'Pet%';
看看是不是想要删除的数据,是的话执行
sqlite>DELETEFROMArtistsWHEREArtistNameLIKE'Pet%';
再次查新内容变更成:
ArtistID|ArtistName
2|BruceHornsby
3|LyleLovett
4|Santana
以上只是介绍了部分常用的SQL用法,SQLite支持的SQL包括:ATTACHDATABASE、BEGINTRANSACTION、comment、COMMIT、TRANSACTION、COPY、CREATEINDEX、CREATETABLE、CREATETRIGGER、CREATEVIEW、DELETE、DETACHDATABASE、DROPINDEX、DROPTABLE、DROPTRIGGER、DROPVIEW、ENDTRANSACTION、EXPLAIN、expression、INSERT、ONCONFLICTclause、PRAGMA、REPLACE、ROLLBACKTRANSACTION、SELECT、UPDATE。
具体用法请自行查新相关文档。
3.2SQLite在编程中的使用
主要是一些SQLite中提供的一些接口函数,下边介绍比较常用的一些接口函数的用法:
1、打开和关闭数据库
使用SQLite3接口操作数据库时都要先打开数据库
intsqlite3_open(constchar*filename,sqlite3**ppDb);
参数即返回值意义如下:
filename:要打开的数据库的文件名
ppDb:用户返回数据库句柄
返回值:SQLITE_OK代表成功,否则为错误码
返回的错误码可以在SQLite3源码的sqlite3.h头文件找到。需要说明的是这些错误是SQLite3编程接口共同使用的。而不是sqlite3_open函数私有。
使用完数据库后关闭:
intsqlite3_close(sqlite3*ppDb);
2、执行SQL语句
SQLite3提供了一个一般化的编程接口,可以对以打开的数据库执行任何SQL语句。这个函数的原型如下:
intsqlite3_exec(sqlite3*pDb,constchar*sql,
int(*callback)(void*context,intnArg,char**azArg,char**azCol),
void*context,char**errmsg);
参数即返回值意义如下:
pDb:已打开的数据库的句柄
sql:字符串,内容是一条或多条sql语句
callback:回调函数
context:传递给回调函数的第一个参数,可称上下文参数
errmsg:指向一个字符串,其内容是对操作中发生的错误的文字描述
返回值:SQLITE_OK代表成功,否则为错误码
回调函数的作用是:当进行查询操作时,每查询到一条记录都会调用一次回调函数,这条记录的内容通过回调函数的参数传入。回调函数的参数既返回值的含义解释如下:
context:调用sqlite3_exec时传入的context指针。
nArg:数据的个数
azArg:字符串数组,有nArg个元素,表示每个字段的值
azCol:字符串数组,有nArg个元素,表示每个字段的名称
返回值:0表示要继续查询否则查询操作结束,对sqllite3_exe函数的调用将返回错误码SQLITE_ABORT.
即使记录中某个字段的类型为整数,它的值也是由C语言的字符串来代表中。
还有就是errmsg参数是一个字符指针变量的地址,通过它将得到一个字符串的首地址。显然,这个字符串的存储空间是在sqlite3_exec函数内动态分配得到的,因此用过后必须释放以免造成内存泄漏。鉴于外界并不知道sqlite3_exe函数内部是如何进行内存分配的。SQLite3平台专门提供了一个函数用于释放这块内存,其原型如下:
voidsqlite3_free(void*p);
其中参数P指向要释放的内存。
3、查询数据库
使用上面的sqlite3_exec函数就可以对数据库进行查询操作,但它使用回调函数作为返回结果的手段,有时不是很方便,因此SQLite3也提供了一个专门的接口进行查询操作,其函数原型如下:
sqlite3_get_table(sqlite3*pDb,constchar*sql,char***pResult,int*nrow,int*ncolumn,char**errmsg);
其中各个参数的含义解释如下:
pDb:已打开的数据库的实例
sql:字符串,内容是一条或多条SQL语句。
pResult:一个(char**)型变量的地址,用于返回查询结果,查询结果由字符串数组代表。
nrow:结果表的行数。
ncolumn:结果的列数
errmsg:指向一个字符串,其内容是对操作中发生的错误的文字描述
这里的参数都好理解,不好理解的是pResult是查询的结果,它是一个字符串数组,因此它的首地址是(char**)地址。虽然它是一个一维的字符串数组,但要以二维的方式去理解,其中前ncolumn个字符串表示结果表的字段名,随后的ncolumn个字符串则是第一条记录的各个字段的值,依次类推。
需要说明的一点是空间的问题,显然pResult所指向的字符串数组及各个字符串所占的空间都是在sqlite3_get_table函数内部动态分配得到的。因此需要使用后进行释放。由于它又不是一块平坦的内存,故也不能用sqlite3_free函数来释放,而必须用下面这个专用的函数:
voidsqlite3_free_table(char**result);
其中,result参数就是查询得到的结果表的首地址。
以上就是在C编程或者QT编程中使用sqlite数据库的相关用法,其他平台的用法尚未验证,这里就不多讲了。
参考资料:
http://baike.baidu.com/view/19310.htm
http://blog.sina.com.cn/s/blog_4c7c21a9010009bm.html