IOS開發之SQLite

SQLite 是一款開源嵌入式文件型數據庫,這個主要是和其他一些C/S架構的關係型數據庫比較而來的,比如MySQL等.

說他是嵌入式,因爲SQLite的所有功能全部包裝在一個dll中,我們只需要使用其中的導出接口就可以操作SQLite數據庫,這樣使得數據存儲功能能夠很方便的集成進用戶的程序中,並運行在客戶程序的進程空間中

說他是文件型,因爲SQLite的數據庫文件就是一個獨立文件(SQLite本身不限制數據庫文件的擴展名),再沒有其他的了,數據,表結構,查詢,視圖等等都保存在這個數據庫文件中,不會依賴任何數據庫環境

SQLite的主要特點:

1.無需部署,0配置,無服務端
2.跨平臺
2.數據文件管理方便
3.較完善的SQL92標準支持,SQLite基本實現了SQL92標準,其他的一些不兼容的地方,可以參看官方相關說明,鏈接:http://www.sqlite.org/omitted.html
4.SQL語句執行速度快,具體的對比數據,網上的評測有很多,這裏就不多說了
5.應用較廣.最著名的集成應該數Android了吧,其他的PHP ,Python等都做了集成,所以還是很不錯的
6.完美的Unicode編碼支持.SQLite的接口中,凡是涉及字符串的都是用UTF8或UTF16編碼交互,有的同時提供這兩種編碼的接口函數,所以多語種支持絕對不是問題(這也是我偏愛SQLite的很重要的原因,呵呵).


SQLite的數據庫操作其實和常規的數據庫操作流程是一樣的:
1.連接數據庫.
2.構造SQL語句並執行
3.對於SELECT語句,可以獲取查詢結果
4.數據庫使用完畢之後,關閉數據庫

這裏說明一下,下面所介紹的函數不會涵蓋所有的API函數,畢竟SQLite針對同一個功能點提供了不同的API函數,主要表現在參數和配置功能上,有需要深入瞭解的朋友可以參考官方的文檔.

1.打開數據庫:
API函數:
int sqlite3_open(
const char *filename, /* 數據庫文件路徑(UTF-8編碼) */
sqlite3 **ppDb /* 輸出: SQLite 數據庫句柄 */
);
int sqlite3_open16(
const void *filename, /* 數據庫文件路徑(UTF-16) */
sqlite3 **ppDb /* 輸出: SQLite 數據庫句柄 */
);
如果調用成功會返回SQLITE_OK,否則返回錯誤碼.

2.構造SQL語句,這裏就不多說了,這和SQLite本身無關,可以根據需要使用適當的方法構造即可,注意傳給SQLite函數的時候,字符串編碼要記得轉換爲UTF8/UTF16

3.執行SQL語句.
在SQLite中執行SQL語句比較簡單的方法是調用函數:
int sqlite3_exec(
sqlite3*, /* 打開的數據庫句柄 */
const char *sql, /* UTF8編碼的SQL語句 */
int (*callback)(void*,int,char**,char**), /* 回調函數,對於SELECT語句返回的結果處理在回調函數中進行 */
void *, /* 傳遞給回調函數的參數 */
char **errmsg /* 相關錯誤信息 */
);

其實sqlite3_exec只是封裝了sqlite3_prepare,sqite3_step(即SQL中的預編譯技術)的,主要目的是爲使用者提供方便,筆者個人覺得使用後者會更加好一點,這裏先做一下總結:

int sqlite3_prepare(
sqlite3 *db, /* 打開的數據庫句柄 */
const char *zSql, /* UTF8編碼的SQL語句,可以參數化 */
int nByte, /* SQL語句的字節長度,可以傳遞-1,即字符串以\0結尾 */
sqlite3_stmt **ppStmt, /* 輸出:預編譯之後的SQL語句句柄 */
const char **pzTail /* 輸出: 指向zSql緩衝區中跳過有效SQL字符串的第一個字節 */
);

int sqlite3_prepare_v2(
sqlite3 *db, /* 打開的數據庫句柄 */
const char *zSql, /* UTF8編碼的SQL語句,可以參數化 */
int nByte, /* SQL語句的字節長度,可以傳遞-1,即字符串以寬字符\0結尾 */
sqlite3_stmt **ppStmt, /* 輸出: 預編譯之後的SQL語句句柄 */
const char **pzTail /* 輸出: 指向zSql緩衝區中跳過有效SQL字符串的第一個字節 */
);

int sqlite3_prepare16(
sqlite3 *db, /* 打開的數據庫句柄 */
const void *zSql, /* UTF16編碼的SQL語句,可以參數化 */
int nByte, /* SQL語句的字節長度,可以傳遞-1,即字符串以寬字符\0結尾 */
sqlite3_stmt **ppStmt, /* 輸出: 預編譯之後的SQL語句句柄 */
const void **pzTail /* 輸出: 指向zSql緩衝區中跳過有效SQL字符串的第一個字節 */
);

int sqlite3_prepare16_v2(
sqlite3 *db, /* 打開的數據庫句柄 */
const void *zSql, /* UTF16編碼的SQL語句,可以參數化 */
int nByte, /* SQL語句的字節長度,可以傳遞-1,即字符串以寬字符\0結尾 */
sqlite3_stmt **ppStmt, /* 輸出: 預編譯之後的SQL語句句柄 */
const void **pzTail /* 輸出: 指向zSql緩衝區中跳過有效SQL字符串的第一個字節 */
);

其中帶參數的SQL語句可以這樣定義參數:

?NNN 
:VVV 
@VVV 
$VVV 
參數編號從1開始,例如:INSERT into db values(?1, ?2)

v2版本函數時SQLite根據需要添加的增強函數,新的程序推薦使用v2版本函數,只需與原來函數的區別,可以參考官方原文

int sqlite3_step(sqlite3_stmt*);
執行一次預編譯SQL語句,在這之前,如果SQL是參數化的,可以調用sqlite3_bind來綁定數據,int,string,blob等等
如果執行成功會返回SQLITE_DONE,如果查詢有結果會返回SQLITE_ROW,並可以通過API獲取結果中的第一行數據,需要獲取下一行數據可以再次調用sqlite3_step直到返回SQLITE_DONE表示後面沒有數據了
如果需要重新對預編譯的SQL綁定數據並執行,需要先reset一下,然後再調用step,即函數:
int sqlite3_reset(sqlite3_stmt *pStmt);

下面是綁定數據到預編譯SQL語句的相關函數:
以下函數的第一個參數指代預編譯的SQL句柄,第二個參數指代綁定的參數編號,對應於參數化的SQL語句中的參數編號:

int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
該函數用於綁定二進制數據BLOB,其中最後一個參數是一個回調函數,當成功綁定數據後,會被調用,一般用於自動釋放對應的緩衝區

int sqlite3_bind_double(sqlite3_stmt*, int, double);
該函數綁定double浮點數

int sqlite3_bind_int(sqlite3_stmt*, int, int);
該函數綁定int整數

int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
該函數用於綁定具有64位長度的整數,對應於C中的long long結構,由於一個int的範圍可能無法滿足超大數據量的要求,所以SQLite也支持64位整數,畢竟SQLite官方聲稱SQLite是支持最大2T的數據的

int sqlite3_bind_null(sqlite3_stmt*, int);
該函數綁定一個空數據到指定列

int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
該函數綁定一段字符串,源字符串是UTF8編碼的

int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
該函數綁定一段字符串,源字符串是UTF16編碼的

int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
該函數綁定以SQLite結構sqlite3_value存儲的通用數據,其中sqlite3_value可以是上述的所有類型,此函數不太常用

int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
該函數綁定指定大小的全零BLOB數據

3.獲取SQL查詢結果
對於SELECT語句,還需要能夠獲取結果.上面也提到調用sqlite3_step之後,對於有結果的查詢會返回第一行結果,這時可以通過API函數獲取當前行的指定字段結果:

const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
該函數以BLOB數據格式獲取對應列的數據,BOLB長度使用sqlite3_column_bytes獲取

int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
該函數可以用於返回BLOB和字符串的字節長度.對於BLOB,兩個函數效果是一樣的,但是對於字符串sqlite3_column_bytes返回的是UTF8編碼的字符串長度,而sqlite3_column_bytes16返回的是UTF16編碼的字符串長度,其間會做必要的字符串格式轉換

double sqlite3_column_double(sqlite3_stmt*, int iCol);
該函數返回double數據列

int sqlite3_column_int(sqlite3_stmt*, int iCol);
該函數返回int數據列

sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
該函數返回64位整數,即long long數據

const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
該函數返回字符串,其中sqlite3_column_text輸出的字符串使用UTF8編碼

sqlite3_column_text16使用UTF16編碼
int sqlite3_column_type(sqlite3_stmt*, int iCol);
該函數返回對應列的數據類型

sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
該函數以sqlite3_value結構體返回數據

上面是根據列ID來獲取對應的列數據的,如果想通過列名稱獲取列數據,則需要將列名稱轉換爲對應的列ID,可以使用下面的函數:
const char *sqlite3_column_name(sqlite3_stmt*, int N);
const void *sqlite3_column_name16(sqlite3_stmt*, int N);
該函數返回對應列的名稱

4.關閉數據庫

int sqlite3_close(sqlite3 * db);
使用該函數可以關閉數據庫
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章