Sqlite是一个流行的,独立的、无服务、零配置、事务性的数据库引擎。它还是开源的。目前最新的版本是3.7.4。它由,Oracle、Symbian、Adobe、Mozilla联合赞助开发。使用的该数据库的公司或者产品有,Google、Toshiba、Skype、Sun、Microsoft、Apple,够出名吧。
Ø 事务准许acid的特性,即原子性、一致性、独立性、持久性。这些特性即便在系统崩溃或者掉电的情况下依然保有。
Ø 零配置,不需要安装或者管理
Ø 实现了大部分的SQL92标准,关于SQL92标准的详细定义请参看:
http://baike.baidu.com/view/1889818.html http://en.wikipedia.org/wiki/SQL-92
sqlite具体支持和不支持的sql特性详细说明资料如下:
http://www.sqlite.org/lang.html
Ø Sqlite数据库文件被封装在一个跨平台的磁盘文件中
Ø Sqlite支持String和blobs大字段存储
Ø 数据库代码占用空间小:全版本少于325KB,精简版小于190KB
Ø Sqlite运行速度在大多数情况下要高于现在流行的c/s架构的数据库引擎
Ø 简单易用的API
Ø 使用C语言编写,并有TCL脚本发行版,以及其他数十种编程语言的发行版
Ø 注释良好的源代码
Ø Sqlite本身只是一个单独的c语言文件,这使你可以很容易的将其整合到其他项目中
Ø Sqlite是独立的,没有特别的依赖
Ø Sqlite支持跨平台,它良好的支持Unix,OS/2,Windows(win32 and WinCE)等系统
Ø Sqlite是开源的
Ø 可以使用独立的CLI(command-line interface)客户端进行管理Sqlite数据库
Ø 代替XML,属性文件:使用Sqlite代替XML,属性文件后,可以省去麻烦的XML,或特殊属性文件的读取与解析,并且可以很好的跨平台,在你的数据更新时获得良好的事务特性
Ø 嵌入式开发:Sqlite可以用于嵌入式开发,由于其占用磁盘和内存空间较小,并且不用去维护
Ø 中小型网站:无配置,且将数据存放在单个文件的便利性
Ø 测试时代理企业级数据库:由于Sqlite的免安装和免配置特性,所以可以替代企业级数据库进行测试
Ø sqlite3_open():该函数打开一个到Sqlite数据库文件的连接并返回一个数据库连接对象。它一般是应用编程调用的第一个Sqlite API,也是其它Sqlite API得以调用的前提。
Ø sqlite3_prepare():该函数将Sql语句转换成一个预编译语句对象,并返回该对象的指针。当然,该函数得以调用的前提是使用sqlite3_open()函数打开一个到数据库的连接。
Ø 值得注意的是,sqlite3_prepare()并不是推荐的函数调用,做为代替,在新版本的Sqlite中推荐使用sqlite3_prepare_v2() 做为代替函数
Ø sqlite3_step():调用该函数,便从sqlite3_prepare()函数所得到的预编译对象中获取一行。
Ø sqlite3_column():该函数用于获取sqlite3_step()得到的一行中,某一列的值,可调用多次以遍历该行。还有一组函数,用于获取该行中有多少列,或者该列的大小,或者获取对应类型的该列值。在此不一一详述,函数名如下:
sqlite3_column_blob()
sqlite3_column_bytes()
sqlite3_column_bytes16()
sqlite3_column_count()
sqlite3_column_double()
sqlite3_column_int()
sqlite3_column_int64()
sqlite3_column_text()
sqlite3_column_text16()
sqlite3_column_type()
sqlite3_column_value()
Ø sqlite3_finalize():该函数用于销毁sqlite3_prepare()所获取的prepared statement,每一prepared statement在使用完成之后都必须调用该函数进行资源回收,以免导致内存泄露
Ø sqlite3_close():关掉先前打开的数据库连接。在连接关闭之前,应先把与该连接关联的所有prepared statements先关闭
应用程序可以使用sqlite3_open()获取单个的数据连接。sqlite3_open()可以用于打开一个已经存在的数据库文件,或者创建一个新的数据库文件。多线程应用程序可以为每一个线程创建一个数据库连接。值得注意的是,没有必要为了访问两个或多个数据库而打开独立的数据库连接。因为,一个数据库连接可以使用“ATTACH”sql命令来同时访问多个数据库。
当开数据库连接后,如何执行一个sql语句。步骤如下:
1, 通过sqlite3_prepare()去创建一个prepared statement
2, 调用sqlite3_step()一次或多次去计算获取prepared statemte的值
3, 在两次sqlite3_step()调用的间隙,调用sqlite3_column()函数去查询、抽取结果集。
4, 调用sqlite3_finalize()方法用来销毁prepared statement
Ø 封装核心接口函数的包装函数:这类函数将以上操作数据库的四个步骤打包进一个函数。这类函数有:sqlite3_exec()、sqlite3_get_table();
Ø 重复使用prepared statement函数:使用sqlite3_reset()函数可以将一个prepared statement复原,这样的好处可以使我们不用调用sqlite3_prepare()函数重复创建多个prepared statement,达到资源复用的目的。更多的情况,可能我们多次prepared statement的sql语句一样,但是参数不一样,比如使用同一个insert语句向数据库中插入多行记录,那么可以在调用sqlite3_step()函数之前或者sqlite3_reset()函数之后,调用sqlite3_bind()函数,将参数绑定进prepared statement.
Ø 扩展sqlite功能的函数:sqlite3_create_collation() 、sqlite3_create_function()、sqlite3_create_module()。详细说明参考资料:http://www.sqlite.org/cintro.html
步骤一:下载相关文件
需要的文件,Sqlite源码包、Sqlite dll包、Sqlite控制台包,分别对应文件:sqlite-amalgamation-3070400.zip、sqlite-dll-win32-x86-3070400.zip、sqlite-shell-win32-x86-3070400.zip。
他们的作用分别是:
C++代码依赖Sqlite源码包中的sqlite3.h头文件,依赖Sqlite dll包中的dll文件
而Sqlite控制台包这可要可无,他主要为我们提供一个数据库可视化管理的界面,它不会直接作用于工程中。
步骤二:根据sqlite3.def文件,生成相应的lib文件
解压Sqlite dll包会发现文件夹中有两个文件sqlite3.def、sqlite3.dll。在dos下切换到该文件夹,执行命令:LIB /DEF:SQLITE3.DEF /MACHINE:IX86 会生成sqlite3.exp、sqlite3.lib两文件。Sqlite3.lib库主要用来连接win32程序
注:如果找不到LIB命令,请将Microsoft Visual Studio 9.0\VC\bin所在的目录添加到环境变量path里
步骤三:将sqlite3.lib、sqlite3.exp、sqlite3.dll文件放入工程所在的目录。
开始安装上面的典型数据库编程来写代码
实例代码如下:
#include "sqlite3.h" #include <iostream> #include <sstream>
using namespace std; sqlite3 * pDB; static int callback(void *NotUsed, int argc, char **argv, char **azColName) {
for(int i = 0 ; i < argc ; i++) { std::cout << azColName[i] << " = " << (argv[i] ? argv[i] : "NULL") << ", " ; }
std::cout<< "\n"; return 0; }
int main() { char* errMsg; sqlite3_stmt * stmt; /*打开一个现有的数据库,或者创建一个新的数据库*/ int res = sqlite3_open("E:\\sql.db", &pDB);//这句好是执行成功的话,pDB就得到了指向打开的数据库的句柄(相当于引用吧)
if( res ){ //如果res返回为,那么久表示打开出错,具体返回(状态码对应意思,查看资料:http://www.sqlite.org/c3ref/c_abort.html std::cout << "Can't open database: "<< sqlite3_errmsg(pDB); sqlite3_close(pDB); return -1; }
/*建表语句*/ string createSql = "create table vincent_test(num int);"; sqlite3_exec(pDB , createSql.c_str() ,0 ,0, &errMsg); if (res != SQLITE_OK) { std::cout << "执行创建table的SQL 出错." << errMsg << std::endl; return -1; } else { std::cout << "创建table的SQL成功执行."<< std::endl; }
/*插入语句*/ res = sqlite3_exec(pDB,"begin transaction;",0,0, &errMsg);//先打开事务 string insertSql = "insert into vincent_test values(3)"; res = sqlite3_exec(pDB,insertSql.c_str(),0,0, &errMsg); if (res != SQLITE_OK) { std::cout << "执行SQL 出错." << errMsg << std::endl; return -1; } res = sqlite3_exec(pDB,"commit transaction;",0,0, &errMsg);//提交事务
/*循环遍历获取结果集语句*/ string querySQL= "select * from vincent_test;";
res = sqlite3_exec(pDB, querySQL.c_str(), callback , 0 , &errMsg);
if (res != SQLITE_OK) { std::cout << "执行SQL 出错." << errMsg << std::endl; return -1; } else { std::cout << "SQL成功执行."<< std::endl; }
sqlite3_close(pDB); return 0; } |
函数API列表:http://www.sqlite.org/c3ref/funclist.html
宏定义常量列表:http://www.sqlite.org/c3ref/constlist.html
结构体对象列表:http://www.sqlite.org/c3ref/objlist.html