一、        什么是Sqlite

         Sqlite是一个流行的,独立的、无服务、零配置、事务性的数据库引擎。它还是开源的。目前最新的版本是3.7.4。它由,OracleSymbianAdobeMozilla联合赞助开发。使用的该数据库的公司或者产品有,GoogleToshibaSkypeSunMicrosoftApple,够出名吧。

二、        Sqlite的特点

Ø  事务准许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支持Stringblobs大字段存储

Ø  数据库代码占用空间小:全版本少于325KB,精简版小于190KB

Ø  Sqlite运行速度在大多数情况下要高于现在流行的c/s架构的数据库引擎

Ø  简单易用的API

Ø  使用C语言编写,并有TCL脚本发行版,以及其他数十种编程语言的发行版

Ø  注释良好的源代码

Ø  Sqlite本身只是一个单独的c语言文件,这使你可以很容易的将其整合到其他项目中

Ø  Sqlite是独立的,没有特别的依赖

Ø  Sqlite支持跨平台,它良好的支持UnixOS/2,Windows(win32 and WinCE)等系统

Ø  Sqlite是开源的

Ø  可以使用独立的CLI(command-line interface)客户端进行管理Sqlite数据库

三、        Sqlite使用的场合

Ø  代替XML,属性文件:使用Sqlite代替XML,属性文件后,可以省去麻烦的XML,或特殊属性文件的读取与解析,并且可以很好的跨平台,在你的数据更新时获得良好的事务特性

Ø  嵌入式开发:Sqlite可以用于嵌入式开发,由于其占用磁盘和内存空间较小,并且不用去维护

Ø  中小型网站:无配置,且将数据存放在单个文件的便利性

Ø  测试时代理企业级数据库:由于Sqlite的免安装和免配置特性,所以可以替代企业级数据库进行测试    

四、        C/C++中使用Sqlite数据库

1.       操作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先关闭

2.       典型的sqlite数据库操作步骤

       应用程序可以使用sqlite3_open()获取单个的数据连接。sqlite3_open()可以用于打开一个已经存在的数据库文件,或者创建一个新的数据库文件。多线程应用程序可以为每一个线程创建一个数据库连接。值得注意的是,没有必要为了访问两个或多个数据库而打开独立的数据库连接。因为,一个数据库连接可以使用“ATTACHsql命令来同时访问多个数据库。

         当开数据库连接后,如何执行一个sql语句。步骤如下:

1, 通过sqlite3_prepare()去创建一个prepared statement

2, 调用sqlite3_step()一次或多次去计算获取prepared statemte的值

3, 在两次sqlite3_step()调用的间隙,调用sqlite3_column()函数去查询、抽取结果集。

4, 调用sqlite3_finalize()方法用来销毁prepared statement   

3.       其它扩展功能函数

Ø  封装核心接口函数的包装函数:这类函数将以上操作数据库的四个步骤打包进一个函数。这类函数有:sqlite3_exec()sqlite3_get_table();

Ø  重复使用prepared statement函数:使用sqlite3_reset()函数可以将一个prepared statement复原,这样的好处可以使我们不用调用sqlite3_prepare()函数重复创建多个prepared statement,达到资源复用的目的。更多的情况,可能我们多次prepared statementsql语句一样,但是参数不一样,比如使用同一个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

 

 

4.       C++操作Sqlite数据库的步骤

步骤一:下载相关文件

需要的文件,Sqlite源码包、Sqlite dll包、Sqlite控制台包,分别对应文件:sqlite-amalgamation-3070400.zipsqlite-dll-win32-x86-3070400.zipsqlite-shell-win32-x86-3070400.zip

他们的作用分别是:

C++代码依赖Sqlite源码包中的sqlite3.h头文件,依赖Sqlite dll包中的dll文件

Sqlite控制台包这可要可无,他主要为我们提供一个数据库可视化管理的界面,它不会直接作用于工程中。

步骤二:根据sqlite3.def文件,生成相应的lib文件

         解压Sqlite dll包会发现文件夹中有两个文件sqlite3.defsqlite3.dll。在dos下切换到该文件夹,执行命令:LIB /DEF:SQLITE3.DEF /MACHINE:IX86  会生成sqlite3.expsqlite3.lib两文件。Sqlite3.lib库主要用来连接win32程序

         注:如果找不到LIB命令,请将Microsoft Visual Studio 9.0\VC\bin所在的目录添加到环境变量path

步骤三:将sqlite3.libsqlite3.expsqlite3.dll文件放入工程所在的目录。

开始安装上面的典型数据库编程来写代码

实例代码如下:

#include "sqlite3.h"

#include

#include

 

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;

}

 

5.       备注:

         函数API列表:http://www.sqlite.org/c3ref/funclist.html

         宏定义常量列表:http://www.sqlite.org/c3ref/constlist.html

         结构体对象列表:http://www.sqlite.org/c3ref/objlist.html