SQLite 中 C/C++ 接口介绍

前端之家收集整理的这篇文章主要介绍了SQLite 中 C/C++ 接口介绍前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

原文链接http://www.jb51.cc/article/p-cyyznbtf-bnx.html


这篇文章简要的介绍了 sqlite 的 C/C++ 接口。

早期版本的 sqlite 很好学是因为他们只提供了 5 个 C/C++ 的接口。但是随着 sqlite 功能增加,新的 C/C++ 接口加入,现在已经有超过 200 个不同的 API 了。这对新人可能是一种阻碍。幸运的是,大部分的 C/C++ 接口都是有特殊用途的,不需要了解。尽管有这么多的入口点,核心的 API 还是相当的简单而且容易使用。这篇文章旨在提供所有能使读者容易理解 sqlite 如何工作的背景信息。

一个独立的接口文档提供了 sqlite 不同的 C/C++ 接口的详细说明。一旦读者理解了操作 sqlite 的基本概念,该文档就可以成为参考手册了。这篇文章只是一个介绍,不会是 sqlite 的完整、权威的参考手册。

1.0 核心对象和接口

sql 数据库引擎的核心任务是计算 sql 语句的值(evaluate statements of sql)。为了完成这个目的,开发者需要了解两个对象:

数据库连接对象(The database connection object):sqlite3
预处理好的语句对象(The prepared statement object):sqlite3_stmt

严格来讲,对于一些封装好的便捷接口 prepared statement object不是必须的,比如sqlite3_exec还有sqlite3_get_table, 在内部求值时都会封装并隐藏这些 prepared statement object。然而,要想充分利用 sqlite,理解 prepared statements 还是有必要的。

Database connection 和 prepared statement 对象由下面列出的一组 C/C++ 接口(interface routine)控制。

sqlite3_open()  
sqlite3_prepare()  
sqlite3_step()  
sqlite3_column()  
sqlite3_finalize()  
sqlite3_close()

上面列出的 6 个 C/C++ 接口还有两个对象组成了 sqlite 的核心功能。理解了这些的开发者在使用 sqlite 时就会很容易了。

注意上面列出的这些接口只是一类接口而不是实际的接口。这些接口都有许多不同的版本。比如,上面列出的一个叫做sqlite3_open()的接口,事实上是由 3 个完全不同的接口组成的:sqlite3_open(),sqlite3_open16()还有sqlite3_open_v2()。上面列表中提到的sqlite3_column()实际上并不存在。列表中提到的 “sqlite3_column()” 实际上是由一簇为了获取不同列类型的接口组成。

下面是核心接口的简要介绍:

sqlite3_open()这个接口打开一个到 sqlite 数据库文件链接并返回一个数据库连接对象。这通常是应用程序调用的第一个 sqlite 的 API,并且也是其他大部分的 sqlite API 所需要的。大部分的 sqlite 接口需要一个指向 database connection object 的指针作为第一个参数,可以认为是数据库连接对象上的方法。这个接口是数据库连接对象的构造器。

sqlite3_prepare()这个接口将 sql 语句转换为一个 prepared statement 对象并返回指向这个对象的指针。这个接口需要之前使用sqlite3_open()返回的数据库连接对象,还有一个包含 sql 语句的文本字符串作为参数。这个 API 实际上并不执行 sql 语句。它仅仅只是准备用于执行的 sql 语句。把每个 sql 语句想象成一个小型的计算机程序。sqlite3_prepare()是为了把那个程序编译成对象代码(object code)。Prepared statement 就是这个对象代码。之后sqlite3_step()运行这个对象代码获取结果。

注意对于新的程序已经不推荐使用sqlite3_prepare()。新的应用推荐使用sqlite3_prepare_v2()接口。

sqlite3_step() 这个接口用于执行之前用sqlite3_prepare()创建的 prepared statement。这个接口只返回结果集的第一条结果。为了获取第二条结果,再调用一次sqlite3_step()。继续调用sqlite3_step()直到语句结束。不返回结果的语句(比如:INSERT,UPDATE,或者 DELETE 语句)调用一次sqlite3_step()就行了。

sqlite3_column()这个接口返回使用sqlite3_step()查询的 prepared statement 的结果集中当前行的某一列。每次调用sqlite3_step()都会产生一个新的 result set row。这个接口可以被调用多次用于获取一行中的不同列。正如上面所提到的,事实上在 sqlite 的 API 中并没有 “sqlite3_column()” 这个函数。相反的,我们这里调用的 “sqlite3_column()” 是为了获取某列中不同类型值的一簇的接口占位符(a place-holder for an entire family of functions)。这类接口中有返回结果大小(如果是字符串或者 BLOB,译注:Binary Large OBject)还有结果集中列数的接口。

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()这个接口关闭之前由调用sqlite3_open()创建的数据库连接。在关闭数据库连接前所有与之关联的 prepared statements 都应该已经被销毁了。

1.1 核心接口和对象的使用方法

一个想要使用 sqlite 的应用程序通常在初始化时使用sqlite3_open()创建一个数据库连接。注意sqlite3_open()既可以用于打开一个现存的数据库,也可以创建并打开一个新的数据库。因为许多的应用程序只使用一个数据库连接,所以就没有理由让一个应用程序多次调用sqlite3_open()创建多个数据库连接 – 同一个数据库或者不同的数据库。有时一个多线程的应用会为不同的线程创建独立的数据库连接。注意,为了访问两个或者多个数据库也没必要创建多个独立的连接。一个单一的数据库连接可以使用ATTACHsql 语句同时访问两个或者多个数据库(译注:http://sqlite.awardspace.info/@R_404_156@/sqlitepg12.htm)。

许多应用在关闭调用sqlite3_close()销毁它们的数据库连接。比如,一个使用 sqlite 作为它的应用程序文件格式(application file format)会在点击 文件/打开(File/Open) 菜单时创建一个数据库连接,在点击 文件/关闭 (File/Close) 菜单关闭这个连接。

要执行 sql 语句,程序需要遵循以下几步:

使用 **sqlite3_prepare()** 创建一个 prepared statement。 通过一次或多次调用 **sqlite3_step()** 查询 prepared statement 的结果。 对于查询来说,在调用 **sqlite3_step()** 后通过调用 **sqlite3_column()** 获取结果。 使用 **sqlite3_finalize()** 销毁 prepared statement。

上述都是为了高效的使用 sqlite 读者所需要知道的。其余的都只是补充和细节。

2.0 核心 API 的便捷封装

sqlite3_exec()是使用一次函数调用完成上述四种接口调用的便捷封装。sqlite3_exec()在处理结果集的每行时调用传入的回调函数sqlite3_get_table()是另一个使用一次函数调用完成上述四种接口调用的便捷封装。sqlite3_get_table()sqlite3_exec()的不同之处是将结果集保存在堆中而不是每次都调用回调函数

需要注意的是sqlite3_exec()sqlite3_get_table()都不能实现核心接口不能完成的事。事实上,这些封装都是完全由核心接口实现的。

3.0 参数绑定与重用 Prepared Statements

在之前的讨论中,都假设每个 sql 语句都只准备一次( prepared once),执行(evaluated),然后销毁。但是,sqlite 允许相同的 prepared statement 被执行多次。通过以下的方法实现:

sqlite3_reset() sqlite3_bind()

sqlite3_step()执行一次或多次 prepared statement 后,通过sqlite3_reset()可以重置并重新执行(evaluated)。对现存的 prepared statement 使用sqlite3_reset()可以避免调用sqlite3_prepare()创建一个新的 prepared statement。对于部分的 sql 语句,调用sqlite3_prepare()的时间和调用sqlite3_step()一样。所以避免调用sqlite3_prepare()性能提升有重大的影响。

通常不会对一个 sql 语句执行(evaluate)多次。更常见的是,执行一个相似的语句。例如,你想通过执行多次 INSERT 语句插入不同的值。为了实现类似的灵活性,sqlite 允许对一条 sql 语句每次“绑定”不同的值。这些值之后可以改变,并且同样的 prepared statement 使用新的值可以二次使用。(译注:说白了就是对一个表一次插入多条数据,每次插入的不同的值在 sql 语句中用通配符占位)

sqlite 中,任何地方都允许插入字符串字面量(string literal),可以使用以下几种形式:

? ?NNN :AAA $AAA @AAA

在上面个的例子中,NNN 代表整型值( integer value ),AAA 是个标识符(identifier)(译注:字母数字组合)。参数的初始值为 NULL。在第一次调用sqlite3_step()之前或立即在调用sqlite3_reset()之后,应用程序可以调用某个sqlite3_bind()接口绑定值到参数上。每次调用sqlite3_bind()都会覆盖之前绑定到相同参数的值。

应用可以按需要提前准备多个 sql prepared statements 并按需要执行(evaluate)。没有严格的限制 prepared statements 的数量

4.0 配置 sqlite

默认的 sqlite 配置对于大部分的应用工作的都挺好的。但有时开发者想要优化设置项去尝试压榨出更多的性能,或者利用一些隐蔽的特性。

sqlite3_config()可以设置 sqlite 全局的,进程级(process-wide)的配置项。sqlite3_config()只能在数据库连接建立后被调用sqlite3_config()允许程序员做以下的事情:

调整 sqlite 如何分配内存,包括为安全敏感(safety-critical)的实时的嵌入式系统和应用程序定义的(application-defined)内存分配器设置为可选的(alternative)内存分配器(memory allocators)。 设置一个进程级的错误日志。 指定一个应用程序定义的页缓存(page cache)。 调整 mutex 的使用,这样就可以使用多种线程模型,或者替换一个程序定义的 mutex 系统。

在进程级的设置完成(configuration is complete)并且数据库连接已经创建后,不同的数据库连接可以通过调用sqlite3_limit()sqlite3_db_config()配置。

5.0 扩展 sqlite

sqlite 包含可以扩展功能的接口。这些接口(routine)包括

sqlite3_create_collation() sqlite3_create_function() sqlite3_create_module() sqlite3_vfs_register()

sqlite3_create_collation()接口用于创建排序文字用的新的校对队列(collating sequences)。sqlite3_create_module()接口用于注册新的虚表实现。sqlite3_vfs_register()创建一个新的 VFS(译注:Virtual File System,虚拟文件系统)。

sqlite3_create_function()接口用于创建新的 sql 函数(function)—— scalar 函数或者 aggregate 函数(译注:http://www.w3schools.com/sql/sql_functions.asp)。新的函数实现通常使用以下的额外接口:

sqlite3_aggregate_context() sqlite3_result() sqlite3_user_data() sqlite3_value()

所有的 sqlite 内建 sql 函数都使用的是这些接口创建的。可以参考 sqlite 的源文件,尤其是 date.c 和 func.c。

共享库或者 DLL 可以作为 sqlite 的可装卸扩展(loadable extensions)(译注:http://www.sqlite.org/cvstrac/wiki?p=LoadableExtensions)。

6.0 其他接口

这篇文章只提到了 sqlite 的一些基础接口。sqlite 库中还包含一些这里没有提到的有用的 API。可以在 sqlite 的 C/C++ 的接口说明中找到完整的函数列表(译注:http://sqlite.org/c3ref/intro.html)。参考此文档可以找到完整和权威的关于 sqlite 接口的信息。

猜你在找的Sqlite相关文章