微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SQLite3 C/C++介绍

An Introduction To The sqlite C/C++ Interface

From:http://www.sqlite.org/cintro.html

这个文档提供了sqlite C/C++接口函数的概述和学习路线。

早期的sqlite版本非常容易学习,以为它只提供了5个C/C++接口函数。随着sqlite性能的提升,新的C/C++接口函数不断涌入,以至于现在有185个不用的API函数。这对新接触sqlite的程序员来说有点难以接受。幸运的是,大部分API函数很少被用到,而且核心API相对来说比较简单且易于使用。这篇文档旨在从编程角度说明sqlite内部是如何工作的。

一个文档, The SQLite C/C++ Interface,提供了sqlite C/C++函数的详细说明。一旦读者了解了sqlite工作的基本原理,那个文档就应该被作为参考文档。这个文档只被作为sqlite的介绍,它既不是一个完整的,也不是一个官方的sqlite API的参考文档。

1.0 核心对象和接口

sql数据库隐形的首要任务是解析sql语句,为了完成这个目的,开发者需要知道两个对象:

严格说, the prepared statement object是不需要的,因为接口函数sqlite3_exec orsqlite3_get_table,提供了对 theprepared statement object的包装和隐藏,是编程更加简单。 不过,为了更好的使用,认识sqlite,对prepared statements 的了解还是有必要的。

The database connection andprepared statement objects 被以下C/C++接口函数使用管理。

这六个C/C++接口例程(下面会说明为什么不叫接口函数)和上面提到的两个对象完成了sqlite的核心功能。开发者如果对它们有一个更好的理解,将会对sqlite的使用打下良好的基础。

注意:上面列出的函数例程是感念上的而不是实际上的。这些例程都有很多个函数版本。例如,sqlite3_open() 实际上有3个细微差别的版本sqlite3_open(),sqlite3_open16() (对UNICODE的支持)andsqlite3_open_v2()(推荐使用的新的API)。而sqlite3_column() 实际上并不存在。上面列出的"sqlite3_column()"代表了一个函数簇,这个函数簇用于从列中取出不同数据类型的数据。

Here is a summary of what the core interfaces do:

sqlite3_open()

这个函数打开一个sqlite数据库的连接并返回一个指向database connection object的指针。这个API通常在应用程序中第一个调用,而且被当作其他sqlite APIs的前提条件。很多sqlite接口函数需要一个指向database connection 的指针当作他们的第一个参数,这些接口函数也可以被认为是database connection object的方法(提供对database_connection的操作)。这个函数构造database connection object(分配内存)。

sqlite3_prepare() 这个函数sql语句转换到 prepared statement object中,并返回一个指向此对象的指针。这个函数需要一个指向database connection的指针和一个sql语句字符串。这个函数并不对sql语句进行求值(^_^,翻译太烂了,原句如下This API does not actually evaluate the sql statement.),它只是对sql语句进行预处理。

注意: sqlite3_prepare() 在新的程序中不提倡使用,另一个新的函数sqlite3_prepare_v2() 应当作为sqlite3_prepare()的替换。

sqlite3_step()

这个接口函数用于对sqlite3_prepare() 创建的prepared statement对象进行求值(将错就错了,evaluate我就翻译成求值了^_^),它首先对返回结果的第一行进行求值。为了对第二行进行evaluate,需要再次调用sqlite3_step()。一直调用sqlite3_step()知道sql语句被完成。不返回结果的sql语句(ex: INSERT,UPDATE,or DELETE statements)只需调用一次sqlite3_step()就OK了。

这个函数和下面的sqlite3_column()配合使用,可以从数据库中拿值(例如查询),你sqlite3_step()一下,拿出一行数据,然后用sqlite3_column_XXX()再把每一列的值拿出来,之后继续sqlite3_step()和sqlite3_column_XXX(),依次拿出下一行的每个值。

sqlite3_column()

这个例程从一个sqlite3_step()处理过的prepared statement 中的当前行中返回一个列的数据。当每次sqlite3_step()被调用后,这个例程可以被调用多次,以从当前行中取出全部列的指。上面已经提到,实际并不存在"sqlite3_column()"函数,它代表了下面列出的函数簇,这些函数可以从prepare_statement中取出不同数据类型的列值,有些函数还可以取出数据大小(if it is a string or BLOB)。

sqlite3_finalize()

这个函数销毁由sqlite3_prepare()创建的prepared statement对象,防止内存泄漏。

sqlite3_close()

函数关闭数据库连接,与此连接相关的prepared statements应在连接关闭前被finalized

1.1 核心函数及对象的典型应用

一个使用sqlite的程序首先使用在初始化时用sqlite3_open()创建一个database connection对象。sqlite3_open()既可以用于打开一个已经存在的数据库也可以用于创建并打开一个新的数据库。因为大多数应用程序只使用一个database connection连接,一个应用程序不应该多次调用sqlite3_open()去打开多个数据库连接。在多线程程序设计中,可能需要为不同的线程创建不同的database connection对象,以打开不同的数据库连接,但是,请注意,没有必要为了访问多个数据库而创建多个database connection对象。使用sql命令ATTACH,就可以让单个database connection对象用于在同一时间访问不同的数据库

应用程序应使用sqlite3_close()关闭时,销毁database connections对象。例如,一个应用程序可能通过File->Open菜单创建database connections对象,而使用File->Close菜单销毁database connections对象。

程序按照以下步骤,运行sql语句:

  1. 使用sqlite3_prepare()创建prepared statement对象。
  2. 调用sqlite3_step()一次或多次,对prepared statement对象进行求值(evaluate)。
  3. 如果是查询(SELECT)命令,在两次sqlite3_step()之间,调用sqlite3_column()函数簇,以取得列值。
  4. 最后使用sqlite3_finalize()销毁prepared statement对象。

上面提到的,都是一个程序员为更高效使用sqlite而需要知道的,下面的内容是一些其他细节。

2.0 对核心函数的封装所带来的便利性

sqlite3_exec()函数对上面的4个步骤进行了封装,以易于使用。传进sqlite3_exec()的回调函数可以对结果集中的每一行进行处理(例如,打印出查询结果)。sqlite3_get_table() 也对上面的4个步骤进行了包装,和sqlite3_exec()不同的是,它将查询结果保存在堆中而不是通过回调函数的方式进行处理。

请注意:sqlite3_exec()sqlite3_get_table()所做的事情都可以使用核心函数来实现。实际上,这两个函数就是通过核心函数实现的。

3.0 绑定参数和重新使用prepared statement对象

在上面的讨论中,我们假设每个sql语句被预处理一次,然后求值(evaluate),最后销毁。其实,sqlite允许相同的prepared statement对象被evaluate多次,这是通过一下函数实现的。

调用一次或多次sqlite3_step()一个prepared statement对象进行evaluate后,通过调用sqlite3_reset()可以让其复位,然后再次被evaluate。在一个已经存在的prepared statement上使用sqlite3_reset(),而不是创建一个新的prepared statement,这避免了调用sqlite3_prepare()所带来的开销。很多时候,sqlite3_prepare()花费的时间都比sqlite3_step()要长,所以避免调用sqlite3_prepare()可以带来性能上的提升。

通常,对同一个sql语句进行多次evaluate是没有用处的,很多时候,大家都想对相似的语句进行evaluate。例如,你可能想对INSERT语句进行多次求值以插入不同的值。顾及到对于类似情况的灵活性,sqlite允许sql语句中包含parameters,这些parameters在evaluate前,绑定到一个值。这些值稍后可以改变,以使相同的prepared statement使用新值再次被evaluate。

sqlite中,parameter有以下几种形式:

  • ?
  • ?NNN
  • :AAA
  • $AAA
  • @AAA

在上面的示例中,NNN是整形,AAA是标识符。一个参数初始化是有一个NULL值。在第一次调用sqlite3_step()之前,或调用sqlite3_reset()之后。程序可以调用sqlite3_bind()函数簇中的一个将参数绑定到一个值上,之后绑定的值将覆盖之前绑定的值。

一个程序允许预处理多行sql语句然后evaluate。sqlite没有对未完成的prepare_statements进行数量限制。

4.0 Extending sqlite

sqlite包含了一些具有扩展功能函数

The sqlite3_create_collation() interface is used to create new collating sequences for sorting text. Thesqlite3_create_module() interface is used to register new virtual table implementations.

The sqlite3_create_function() interface creates new sql functions - either scalar or aggregate. The new function implementation typically makes use of the following additional interfaces:

All of the built-in sql functions of sqlite are created using exactly these same interfaces. Refer to the sqlite source code,and in particular thedate.c andfunc.c source files for examples.

5.0 其他接口

本文档介绍了sqlite的基本接口函数sqlite库包含了许多其他有用的API函数,但并不在这里介绍。参考C/C++ Interface Specification这个文档,以获取官方关于sqlite接口的信息。

相关文档

SQLite 权威指南_中文

SQLite学习手册

示例代码http://www.jb51.cc/article/p-drnlptph-ce.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐