SQLite是一款很有名气的小型开源跨平台数据库,作为目前最流行的开源嵌入式关系型数据库,在系统结构设计中正在扮演着越来越重要的角色。

本文主要沿着 http://www.cppblog.com/weiym/archive/2012/10/16/193357.html 这篇文章里面的学习指导思想,来一步步学习SQLite,为的是快速在实际开发中利用好SQLite。

1. SQLite的优缺点以及适用场合

1. 1 优点

轻量级:       与传统的C/S模式的数据库软件不同,它是进程内的数据库引擎,不存在客户端和服务器。使用SQLite,只需要带上一个几百K大小的动态库就可以:
    绿色组件:     SQLite的核心引擎本身不依赖第三方软件,即插即用。
    单一文件:      数据库中所有的信息(比如表、视图、触发器等)都保存在单个文件内,可以拷贝到其他地方,照用不误。
    跨平台 :        不仅仅支持主流操作系统(Windows/Linux),还支持很多小型嵌入式系统(Android,WP,Vxworks)。
    查询效率极高 : SQLite的API不区分当前数据库是保存在内存中还是在磁盘文件中,为了提高效率,可以切换为内存方式。只需要在开始时将数据库载入内存,读写完成后,再把内存数据库dump会磁盘文件上就可以,读写内存比读写磁盘快很多倍。

1.2 缺点

并发访问的锁机制: SQLite在并发读写方面的性能一直不太理想,在有大量insert,update访问时,不建议使用。

SQL标准支持不全 :

1.3适用场合

适合查询速度要求较高,内存占用较少的场合,尤其是嵌入式操作系统,如各种手机操作系统,低并发web(99.9%网站是低并发),php环境里原生支持SQLite,asp.net/.net winform里可以很方便的使用System.Data.SQLite.

SQLite本身是C写的,自带的API接口也是C接口,所以用C/C++来使用是最直接的了。对于Java语言来说,可以通过SQLite的JDBC接口方式使用SQLite,对于Python,pysqlite是操作SQLite的首选,它已经是Python的标准库之一。

SQLite使用的授权协议时Public Domain协议,可以大胆的使用。

2. 使用SQLite

有几种使用方式,一种是直接把sqlite源码嵌入到系统中去,另一种是通过dll等开发库来调用相关函数接口。下面先介绍源码嵌入的方式。

首先去SQLite官网上面下载最新版的源码,http://www.sqlite.org/download.html,我下载的是sqlite-amalgamation-3080704.zip版本。

解压此压缩包,得到如下几个文件:     ,往你的项目里面添加上述文件(除了shell.c文件),然后编译就行。

这样想想,如此强大的SQLite,真正起作用的,只有一个c文件和两个h文件,不由得佩服开发者。在sqlite3.c中实现了全部的SQLite库中的内容,sqlite3.h定义了sqlite3.c的接口函数,因此很容易整合进工程。

然后介绍dll调用开发方式。

在Windows平台下调用SQLite3的接口,可以在上述网站下载 “Precompiled Binariers For Windows”下面的sqlite-dll-win32-x86-XXXX.zip版本,解压后会得到两个文件, ,def文件用来定义一个dll的API导出文件。我们可以根据dll和.def文件来生成一个lib文件,供程序调用。

3. SQLite的接口函数

在SQLite中,有两个核心对象,分别为database_connection和prepared_statement 。

database_connection对象sqlite3 是 通过sqllite3_open()函数创建并返回的,在应用程序使用任何其他SQLite接口函数之前,必须先调用该函数用于初始化数据库。

prepared_statement对象 sqlite3_stmt,可以简单理解为 编译后的SQL语句,所有SQL语句执行相关的函数 都需要该对象作为输入参数用于完成指定SQL操作。

  1. sqlite3_open             打开一个数据库连接,创建并且返回 sqlite3  对象
  2. sqlite3_prepare_v2     将制定SQL语句转换成sqlite3_stmt对象
  3. sqlite3_step              单步执行sqlite3_stmt对象
  4. sqlite3_column           返回sqlite3_stmt所在行的指定column的值
  5. sqlite_finalize            销毁sqlite3_stmt对象。所有sqlite3_stmt对象在使用完后必须销毁,防止内存泄露。
  6. sqlite3_close             关闭数据库连接,销毁sqlite3 对象
  7. sqlite3_reset             让执行过的sqlite3_step()的sqlite3_stmt重新执行,相当于将游标返回到开始位置重新读取数据,执行效率比新建一个stmt高
  8. sqlite3_bind               用于INSERT SQL,当同一个INSERT SQL要插入一系列数据时使用,每次sqlite3_step后需要重新bind数据
  9. sqlite3_exec               封装了一系列执行函数,执行制定的SQL语句,并且将查询结果返回给回调函数。

编程过程中需要注意的地方:

1. 调用sqlite3_exec时,对于第五个参数,errmsg来说,如果sql语句执行出错,那么从内部实现上来看,有如下操作:

内部会调用sqlite3Malloc为pzErrMsg分配内存,并且将对应的错误信息拷贝到pzErrMsg中去,sqlite3_exec函数返回时,通过printf(“%s”,errmsg)来提示具体的错误信息,这里,还需要手动做释放错误提示的内存空间,否则会有内存泄露。

2. sqlite3_exe的回调函数,触发条件为每次成功获取新行后,就会触发回调函数,也就是说,当前表中有多少行符合查询结果,那就调用多少次回调函数。

这是sqlite_exec中具体执行回调函数的语句,它嵌套在while(1)大循环里面,可以看出,如果回调函数返回值不为0的话,即使查询结果是存在的,sqlite_exec会将本次查询结果设置为SQLITE_ABORT,从而打印出错误的函数提示,它将停止后续的查询,直接退出sqlite_exe的while(1)大循环。所以,sqlite_exe中的回调函数,返回值一定要为0,和查询的结果和次数都无关。

对于更新、删除、插入等不需要回调函数的操作,sqlite3_exec的第三、第四个参数可以传入0或者NULL

为了防止垃圾数据,在加载数据库的时候,需要先删除表操作。

const char *sql_drop_table="drop table if exists t";

sqlite3_exec(db,sql_drop_table,0,0,&errmsg);

如果不进行上述操作,同样的插入,每次会在之前表的数据基础上进行。

3. sqlite3_exe中的第五个参数,传入类型是指向指针的指针,所以,如果errmsg定义成 char *errmsg,那么传入参数要写成&errmsg才符合要求。

4. sqlite3_get_table函数用于非回调函数查询结果,这里面,第三个参数比较难理解,先记录如下。

pnRow为查询的有效结果的行数指针,pnColumn为查询的每行有多少列,pzErrmsg为错误提示信息。

pazResult这个需要好好解释一下,它有三个*,它是一个一维数组,以下述的表为例子:

要把,这么些内容全部存在 一维指针数组中,既高效又边界,SQLite中是这样来处理的。

假设char **dbResult; sqlite3_get_table中传入的第二个参数值为 &dbResult,那么,根据上表的构造,select * 查询出来的结果应该是这样的,

nRow = 3,代表结果有3行, nColumn = 2,代表每行有2个字段,dbResult为一维指针数组,共有【(nRow+1)*nColumn】个元素,其内存布局如下:

这样的布局,感觉很巧妙。dbResult的0~nColumn为字段名称,从nColumn索引开始才是真正的数据。

还是一样,我们给进去的只是指针的指针,传出来这么多内容,肯定是需要释放对应的内存。无论非回调的查询是成功还是失败,都必须调用sqlite3_free_table来释放内存,防止内存泄露。

4. 在编写sql语句时,建议设置一个局部较大的数组sqlcmd,采用snprintf(sql_cmd,"CREATE TABLE datapro(package INTEGER,offset \
   INTEGER,lklen INTEGER,base INTEHER,link INTEGER,err INTEGER);");来格式化sql命令到数组中去,然后再传入函数。

5. 在执行sqlite_step时,当返回值不为SQLLITE_ROW(此时,代表操作执行成功)时,最好要调用sqlite3_reset来复位内部虚拟机。这是legcy版本的step函数,官方推荐使用v2版本的众多接口函数。

sqlite3_exe类的函数可以完成大部分数据库需求,但是对于插入、查询二进制数据,就无能为力了。对于此类需求,sqlite引入了sqlite3_stmt数据类型,它里面存储被SQLite 解析后的SQL语句内容,因此,可以插入二进制数据,对于表的字段类型为blob类型。

参考链接:

SQLite3 C/C++ 开发接口简介

SQlite3使用总结

SQLite的官方主页:
http://www.sqlite.org/

SQLite中文站:
http://www.sqlite.com.cn/

System.Data.SQLite:
http://sqlite.phxsoftware.com/

sql学习笔记之 嵌入式数据库(sqlite,firebird)
http://www.cnblogs.com/ljzforever/archive/2010/03/09/1681453.html

SQLite学习心得的更多相关文章

  1. 我的MYSQL学习心得(一) 简单语法

    我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  2. 我的MYSQL学习心得(二) 数据类型宽度

    我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  3. 我的MYSQL学习心得(三) 查看字段长度

    我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  4. 我的MYSQL学习心得(四) 数据类型

    我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(五) 运 ...

  5. 我的MYSQL学习心得(五) 运算符

    我的MYSQL学习心得(五) 运算符 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  6. 我的MYSQL学习心得(六) 函数

    我的MYSQL学习心得(六) 函数 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

  7. 我的MYSQL学习心得(七) 查询

    我的MYSQL学习心得(七) 查询 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

  8. 我的MYSQL学习心得(八) 插入 更新 删除

    我的MYSQL学习心得(八) 插入 更新 删除 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得( ...

  9. 我的MYSQL学习心得(九) 索引

    我的MYSQL学习心得(九) 索引 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

随机推荐

  1. C# 采用线程重绘图形要点记录

    大家都知道J2ME 采用一个线程去获取数据,然后得到数据后更新屏幕是件很容易的事情,比如Thread{public void run(){ getData();repaint(); } }这样做就OK ...

  2. Android Activity界面切换添加动画特效

    在Android 2.0之后有了overridePendingTransition() ,其中里面两个参数,一个是前一个activity的退出两一个activity的进入, @Override pub ...

  3. Android 滑动效果基础篇(四)—— Gallery + GridView

    Android系统自带一个GridView和Gallery两个控件,GridView网格显示,Gallery单个浏览,两者结合起来可以真正实现Gallery浏览图片效果. 本示例通过GridView和 ...

  4. sublime php语法检查

    安装sublimelinter 安装sublimelinter-php 设置sublimelinter 进入SublimeLinter文件夹改动 SublimeLinter.sublime-setti ...

  5. cocos2dx libiconv 转码

    iconv下载(Android)已编译完的iconv包(用这个即可) ios自带libiconv,只需#include <iconv.h>即可  步骤 1.libiconv解压文件放置 直 ...

  6. 在Linux使用mingw32来编写win32程序

    MinGW - Minimalist GNU For Windows Mingw32 是 GNU 計畫工具的集合,包含了大量的標頭檔(header files).函式庫與指 令程式.目的在提供免費的工 ...

  7. 详解MYSQL数据库密码的加密方式及破解方法

    MYSQL加密方式:http://blog.csdn.net/listeningsea/article/details/8139641

  8. 美H1B签证额满,硕士以上学位仍可申请

    美国公民与移民服务局6月1日宣布,2007会计年度的工作签证H1B名额已经用完,下年度的申请从明年4月1日开始.但在美国获得硕士以上学位的高学历者仍可申请. 据北美世界日报报道,美国移民律师协会对连续 ...

  9. Autowired properities class

    1. Properties类 @ConfigurationProperties(locations = "classpath:build.properties") @JsonInc ...

  10. linux下 cmatrix的安装和使用

    安装过程 wget http://www.asty.org/cmatrix/dist/cmatrix-1.2a.tar.gztar xvf cmatrix-1.2a.tar.gzcd cmatrix- ...