上一篇:SQLite——世界上部署最广泛的开源数据库(简介)
引言:
作为一种轻量级、嵌入式关系型数据库,SQLite已经成为许多应用和系统的首选解决方案。它是一个开源软件库,以小型、快速和易于使用而著称。为了方便C/C++程序员使用SQLite,SQLite提供了官方的C/C++接口。这个接口允许开发人员在他们的程序中使用标准的C/C++函数来操作SQLite数据库,包括查询和更新数据,管理数据库连接和事务等。
SQLite拥有超过225个API。但是,大多数API都是可选的,并且非常专业并且可以被初学者忽略。核心API体积小、简单且易于学习。本文总结了核心API。
后续文章陆续阐述更为详细SQLiteC/C++接口,提供详细介绍的适用于SQLite的所有C/C++API的规范。本文供了解SQLite的基本操作原理,该文档应作为参考指导。本文仅供介绍之用,不是SQLiteAPI的完整或权威参考。1
编写不易,有用的朋友点个赞或加粉一下万分感谢!300名内回关!
一.核心接口简介
以下两个对象和八个方法构成了基本要素SQLite接口的元素:
- sqlite3_open():用于打开或创建一个SQLite数据库文件,并返回一个可用于访问该数据库的数据库连接对象。如果指定的数据库文件不存在,则函数将自动创建新的数据库文件。
- sqlite3_prepare():用于编译和解析SQL语句并创建一个新的预处理语句对象。在编译SQL语句时,会将语句进行语法和语义分析,检查其中的误差,并将其转换为一个内部表示以供SQLite引擎进行操作。
- sqlite3_stmt:表示SQLite预处理语句。预处理语句在编译SQL语句时用于管理和执行SQL语句中的参数、SQL语句的编译结果以及查询结果的迭代。
- 在SQLite中,预处理语句使用和相关函数编译创建,其中返回一个指向结构体的指针。预处理语句可以存储为通常的命名变量或使用函数内部的栈分配。一旦创建,预处理语句就可以在使用执行它之前,通过系列函数向其中绑定数据。执行预处理语句的迭代时,将获取查询结果的行并使用类似
- sqlite3_bind():用于将输入参数绑定到SQLite预处理语句中。预处理语句在编译SQL语句时,其中包含位置参数'?'的语句,通过对预处理语句使用sqlite3bind()函数将参数值设置到预处理语句上,然后使用sqlite3_step()执行预处理语句。sqlite3_step():用于迭代在SQLite数据库中执行的SELECT语句的结果行、插入数据、更新数据或删除数据。它通过将查询结果的行迭代器向下移动一行来获取结果集中的下一行数据,并返回SQLITEROW指示更多行可用。如果结果集中没有更多行,则迭代器将停留在最后一行,并返回SQLITE_DONE。
- sqlite3_column():SQLiteC/C++接口中的一个函数,它用于获取SELECT查询语句中返回的结果集中指定列的值。该函数通过提供列索引或列名来定位指定的列,并根据该列的数据类型返回值。sqlite3_finalize()→sqlite3_stmt的析构函数。
- sqlite3_close():关闭打开的SQLite数据库连接。在使用完SQLite数据库之后,调用sqlite3close()函数会释放相关资源,包括数据库连接、预处理语句和命令对象等,从而避免内存泄漏和资源浪费。
- sqlite3_exec():在数据库中执行一条或多条SQL语句(例如,查询、插入、更新和删除等)。并且它将一条或多条SQL语句作为一个字符串作为参数进行调用,这使得执行SQL语句非常方便。
二.核心对象和接口
SQL数据库引擎的主要任务是评估SQL语句的SQL。为此,开发人员需要两个对象:
数据库连接对象:sqlite3
预准备语句对象:sqlite3_stmt
严格来说,预准备语句对象不是必需的,因为可以使用便利包装器接口,sqlite3_exec或sqlite3_get_table,这些便利包装器封装和隐藏预准备语句对象。然而,要充分利用SQLite,需要了解准备好的语句。
控制数据库连接和预准备语句对象由下面列出的一小组C/C++接口函数。
sqlite3_open()
sqlite3_prepare()
sqlite3_step()
sqlite3_column()
sqlite3_finalize()
sqlite3_close()
注意,上面的函数列表是概念性的,而不是实际的。其中许多函数都有多个版本。例如,上面的列表显示了一个函数命名为sqlite3_open(),而实际上有三个单独的函数以略有不同的方式完成相同的事情:sqlite3_open()、sqlite3_open16()和sqlite3_open_v2()。该列表提到了sqlite3_column(),而实际上并不存在这样的函数。列表中显示的“sqlite3_column()”是提取列的整个函数系列各种数据类型的数据。
以下是核心接口的功能摘要:
sqlite3_open()
这个函数打开与SQLite数据库文件的连接并返回数据库连接对象。这通常是第一个SQLiteAPI应用程序进行的调用是大多数其他应用程序的先决条件SQLiteAPI。许多SQLite接口需要指向数据库连接对象作为其第一个参数,并且可以被视为数据库连接对象上的方法。此函数是数据库连接对象的构造函数。
sqlite3_prepare()
这个函数将SQL文本转换为预准备语句对象并返回指针到该对象。此接口需要数据库连接指针由对sqlite3_open()的先前调用和包含要准备的SQL语句。此API实际上不会评估SQL语句。它只是准备用于评估的SQL语句。将每个SQL语句视为一个小型计算机程序。目的ofsqlite3_prepare()是将该程序编译为目标代码。预准备语句是目标代码。sqlite3_step()接口然后运行目标代码以获取结果。新应用程序应始终调用sqlite3_prepare_v2()的sqlite3_prepare()。较旧的sqlite3_prepare()保留用于向后兼容性。但是sqlite3_prepare_v2()提供了很多更好的界面。
sqlite3_step()
此函数用于评估已准备好的语句以前由sqlite3_prepare()接口创建。声明被评估到第一行结果可用。若要前进到结果的第二行,请再次调用sqlite3_step()。继续调用sqlite3_step(),直到语句完成。不返回结果的语句(例如:INSERT、UPDATE或DELETE语句)在对sqlite3_step()的单次调用中运行到完成。
sqlite3_column()
用于检索SQLite查询语句的结果集中的列数据。这些函数采用不同的数据类型并提供不同的功能,因此可以根据需要具体选择某个函数。在SQLite查询结果集中的每列数据类型都可以是NULL、整数、浮点数、字符串、二进制数据或其他类型,因此需要根据实际情况使用不同的`sqlite3_column_*()`函数。以下是常用的`sqlite3_column_*()`函数列表:sqlite3_column_blob()返回BLOB类型
- sqlite3_column_bytes()返回单字节无符号数
- sqlite3_column_bytes16()返回双字节无符号数
- sqlite3_column_count()返回查询到记录的数量
- sqlite3_column_double()返回双精度值
- sqlite3_column_int()返回32位整数结果
- sqlite3_column_int64()返回64位整数结果
- sqlite3_column_text()返回UTF-8文本结果
- sqlite3_column_text16()返回UTF-16文本结果
- sqlite3_column_type()返回结果的数据类型
- sqlite3_column_value()返回结果为未受保护的sqlite3_value对象
sqlite3_finalize()函数:
与sqlite3_prepare()函数配对使用,如果使用了sqlite3_prepare()函数则必须使用调用此函数以避免内存泄漏。
sqlite3_close()
此函数关闭以前由调用打开的数据库连接更改为sqlite3_open()。与连接应在关闭之前完成连接。
三核心函数和对象的典型用法
应用程序通常会在初始化期间使用sqlite3_open()创建单个数据库连接。请注意,sqlite3_open()可用于打开现有数据库文件或创建并打开新的数据库文件。虽然许多应用程序仅使用单个数据库连接,但有应用程序没有理由不能多次调用sqlite3_open()为了打开多个数据库连接-要么到相同的数据库或不同的数据库。有时是多线程应用程序将为每个线程创建单独的数据库连接。请注意,单个数据库连接可以访问两个或多个数据库,因此没有必要为每个数据库文件建立单独的数据库连接。
许多应用程序在关机时使用对sqlite3_close()的调用来破坏其数据库连接。或者,例如,应用程序使用SQLite作为其应用程序文件格式打开数据库连接以响应“文件”/“打开”菜单操作然后销毁相应的数据库连接作为响应到“文件/关闭”菜单。
若要运行SQL语句,应用程序将执行以下步骤:
使用sqlite3_prepare()创建预准备语句。
通过调用sqlite3_step()one来评估预准备语句或更多次。
对于查询,通过调用sqlite3_column()来提取结果对sqlite3_step()的两次调用。
调用sqlite3_finalize()来sqlite3_prepare()创建的语句。以上是使用SQLite真正需要了解的全部内容有效。剩下的就是优化和细节了。
四.围绕核心函数的便利包装
sqlite3_exec() 接口是一个方便的包装器,可以通过一次函数调用执行以上所有四个步骤。传递给 sqlite3_exec() 的回调函数用于处理结果集中的每一行数据。sqlite3_get_table() 是另一个方便的包装器,也执行以上所有四个步骤。与 sqlite3_exec() 不同的是,sqlite3_get_table() 将查询的结果存储在堆内存中,而非通过回调函数调用处理数据。
需要注意的是,sqlite3_exec() 和 sqlite3_get_table() 都不做任何无法通过核心函数实现的工作。事实上,这些包装器纯粹是通过核心函数实现的。五.绑定参数和重用预准备语句
在之前的讨论中,我们默认每个 SQL 语句只被准备一次,执行完后便会被销毁。然而,SQLite 允许同一个准备好的语句被多次执行。这可以使用以下函数实现:
sqlite3_reset()
sqlite3_bind()
在通过对sqlite3_step()的一个或多个调用计算准备好的语句后,可以重置它,以便由调用sqlite3_reset()。将sqlite3_reset()视为倒带准备好的语句程序回到开头。在现有预准备语句上使用sqlite3_reset()而不是创建新的预准备语句可避免对sqlite3_prepare()的不必要调用。对于许多SQL语句,所需的时间运行sqlite3_prepare()等于或超过sqlite3_step()所需的时间。因此,避免调用sqlite3_prepare()可以给显著的性能改进。
评估完全相同的SQL通常没有用处语句不止一次。更常见的是,人们想要评估类似的语句。例如,您可能希望计算INSERT语句多次使用不同的值。或者,您可能想要评估在WHERE子句中使用不同的键多次执行同一查询。为了适应因此,SQLite允许SQL语句包含在计算之前与值“绑定”的参数。这些值可以稍后更改,可以计算相同的预准备语句第二次使用新值。
SQLite允许参数在字符串文本、允许使用blob文本、数值常量或NULL在查询或数据修改语句中。(DQL或DML)(参数不得用于列名或表名,或作为约束或默认值的值。(DDL))参数采用以下形式之一:
?
?NNN的
:AAA级
$AAA级
@AAA级
在上面的示例中,NNN是一个整数值,AAA是一个标识符。参数的初始值为NULL。在首次调用sqlite3_step()之前或立即调用在sqlite3_reset()之后,应用程序可以调用sqlite3_bind()接口来附加值到参数。每次调用sqlite3_bind()都会覆盖同一参数上的先前绑定。
允许应用程序提前准备多个SQL语句并根据需要对其进行评估。未完成的已编制报表的数目没有任意限制。某些应用程序在启动时多次调用sqlite3_prepare()来创建他们需要的所有准备好的语句。其他应用程序保留最近使用的预准备语句的缓存,然后在可用时从缓存中重用预准备语句。另一种方法是仅在以下情况下重用准备好的语句在循环中。
六.配置SQLite
SQLite的默认配置适用于大多数应用程序。但有时开发人员想要调整设置以尝试挤出性能提高一点,或者利用一些晦涩难懂的功能。
sqlite3_config()接口用于使全局的、进程范围的SQLite的配置更改。sqlite3_config()接口必须在创建任何数据库连接之前调用。sqlite3_config()接口允许程序员执行以下操作:
调整SQLite进行内存分配的方式,包括设置适用于安全关键型的备用内存分配器实时嵌入式系统和应用定义的内存分配器。
设置进程范围的错误日志。
指定应用程序定义的页面缓存。
调整互斥锁的使用,使其适用于各种线程模型,或将应用程序定义的互斥锁系统。
在完成进程范围的配置并创建数据库连接后,可以使用以下命令配置单个数据库连接调用sqlite3_limit()和sqlite3_db_config()。
七.除了以上核心接口我们还可以使用扩展SQLite接口
SQLite包含可用于扩展其功能的接口。此类函数包括:
sqlite3_vfs_register()向SQLite引擎注册自定义VFS(VirtualFileSystem,虚拟文件系统)。通过注册自定义VFS,开发人员可以在SQLite数据库中使用自己的文件访问方法,从而实现自定义的文件读写操作
sqlite3_create_collation()创建自定义排序规则(collation),以扩展SQLite数据库的功能。该函数允许开发人员通过提供自己的代码,向SQLite引擎添加自定义排序规则,用于控制SQLite数据库中字符串的排序。
sqlite3_create_module()创建自定义的SQLite扩展模块,以扩展SQLite数据库的功能。该函数允许开发人员通过提供自己的代码,向SQLite引擎添加自定义的数据库引擎、函数、虚拟表或其他扩展模块。
sqlite3_create_function()创建自定义的SQL函数,以扩展SQLite数据库的功能。该函数允许开发人员通过提供自己的代码,向SQLite引擎添加自定义函数,用于执行数据处理、转换和计算操作等。
新函数实现通常使用以下附加接口:
sqlite3_aggregate_context()用于获取或设置用于聚合函数的上下文。在使用自定义聚合函数时,开发人员可以使用
sqlite3_result()在聚合函数中设置“最终结果”。在使用自定义聚合函数时,开发人员可以使用 函数设置聚合函数的最终结果,该结果将作为查询的返回值。
sqlite3_user_data()获取与自定义聚合函数关联的数据指针。在使用自定义聚合函数时,开发人员可以使用 函数获取与聚合函数关联的特定数据,如函数参数、全局配置等。
sqlite3_value()获取 SQL 语句中查询结果中的特定值。在编写自定义聚合函数时,开发人员可以使用 函数获取 SQL 语句中查询结果中的某个值,并在自定义聚合函数中使用它。
SQLite的所有内置SQL函数都是使用这些相同的接口。请参阅SQLite源代码,特别是date.c和func.c源文件例如。
共享库或DLL可用作SQLite的可加载扩展。
八.其他接口
本文只提到最重要和最常见的使用了SQLite接口。SQLite库包括许多其他实现有用的API此处未描述的功能。构成SQLite的函数的完整列表应用程序编程接口可在C/C++接口规范中找到。有关以下内容的完整和权威信息,请参阅该文档所有SQLite接口。参考文献:
1.AnIntroductionToTheSQLiteC/C++Interface