SQLite 中 C/C++ 介面介紹
這篇文章簡要的介紹了 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() 建立多個資料庫連線 – 同一個資料庫或者不同的資料庫。有時一個多執行緒的應用會為不同的執行緒建立獨立的資料庫連線。注意,為了訪問兩個或者多個資料庫也沒必要建立多個獨立的連線。一個單一的資料庫連線可以使用 ATTACH SQL 語句同時訪問兩個或者多個資料庫(譯註:http://sqlite.awardspace.info/syntax/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之C介面SQLite
- C++中的基本變數型別介紹C++變數型別
- C++標準庫、C++標準模版庫介紹C++
- C++ 列舉型別介紹C++型別
- Sqlite 介紹及應用SQLite
- C++呼叫C介面C++
- C++ 的關鍵字(保留字)完整介紹C++
- CLion 2022 mac(C/C++整合開發環境)功能介紹MacC++開發環境
- C/C++在哪些方面有區別?詳情介紹如下C++
- C++ 類建構函式初始化列表介紹C++函式
- 【c&c++】glib介紹C++
- 編譯 TensorFlow 的 C/C++ 介面編譯C++
- c++語言教程——01 c++的簡介C++
- C++ 編譯依賴管理系統分析以及 srcdep 介紹C++編譯
- JSON for Modern C++ 庫的介紹與使用示例程式碼JSONC++
- C++ 容器介面卡C++
- Nacos 介面詳細介紹
- SQLite簡介SQLite
- 簡單介紹python中的mock介面開發PythonMock
- 在定義C++, C通用介面函式時讓C++介面支援預設引數C++函式
- C++中scanf和printf系列函式簡介C++函式
- C++庫封裝JNI介面——實現java呼叫c++C++封裝Java
- Android Native C/C++ 使用OpenSSL EVP介面AndroidC++
- FFT原理及C++與MATLAB混合程式設計詳細介紹FFTC++Matlab程式設計
- Halcon介面介紹 第二講
- C/C++語言新增“函式過載”功能簡單介紹和使用方法C++函式
- sqlite輕量型資料庫的介紹及應用SQLite資料庫
- C++移動建構函式以及move語句簡單介紹C++函式
- C++ 引用型別簡介C++型別
- C++ 介面(純虛擬函式)C++函式
- public interface View介面和public interface ViewResolver介面介紹View
- hadoop實戰3(web管理介面介紹及NN,DN,SNN介紹)HadoopWeb
- C/C++中的constC++
- HDI硬體裝置介面介紹
- 遠控介紹及介面編寫
- 詳細介紹C++多執行緒獲取返回值的方法C++執行緒
- 【C++】requires關鍵字簡介C++UI
- Apache IoTDB C# SDK 介紹ApacheC#
- C#各類集合介紹C#