SQLite是一款開源嵌入式文件型數(shù)據(jù)庫,這個主要是和其他一些C/S架構(gòu)的關(guān)系型數(shù)據(jù)庫比較而來的,比如MySQL等。
說他是嵌入式,因為SQLite的所有功能全部包裝在一個dll中,我們只需要使用其中的導(dǎo)出接口就可以操作SQLite數(shù)據(jù)庫,這樣使得數(shù)據(jù)存儲功能能夠很方便的集成進用戶的程序中,并運行在客戶程序的進程空間中
說他是文件型,因為SQLite的數(shù)據(jù)庫文件就是一個獨立文件(SQLite本身不限制數(shù)據(jù)庫文件的擴展名),再沒有其他的了,數(shù)據(jù),表結(jié)構(gòu),查詢,視圖等等都保存在這個數(shù)據(jù)庫文件中,不會依賴任何數(shù)據(jù)庫環(huán)境
SQLite的主要特點: 1。無需部署,0配置,無服務(wù)端 2??缙脚_ 2。數(shù)據(jù)文件管理方便 3。較完善的SQL92標(biāo)準(zhǔn)支持,SQLite基本實現(xiàn)了SQL92標(biāo)準(zhǔn),其他的一些不兼容的地方,可以參看官方相關(guān)說明,鏈接: http://www./omitted.html 4。SQL語句執(zhí)行速度快,具體的對比數(shù)據(jù),網(wǎng)上的評測有很多,這里就不多說了 5。應(yīng)用較廣。最著名的集成應(yīng)該數(shù)Android了吧,其他的PHP ,Python等都做了集成,所以還是很不錯的 6。完美的Unicode編碼支持。SQLite的接口中,凡是涉及字符串的都是用UTF8或UTF16編碼交互,有的同時提供這兩種編碼的接口函數(shù),所以多語種支持絕對不是問題(這也是我偏愛SQLite的很重要的原因,呵呵)。
好了,下面說說基于C API的SQLite操作,這里謝絕討論其他的一些包裝庫,這不是本文的范圍,當(dāng)然SQLite的接口包裝庫函數(shù)還是很多的,基本覆蓋各種主流開發(fā)語言。如基于Object Pascal的sqlitesimpledelphi,想了解這個庫的朋友可以查看我的其他博文: Delphi 2010下使用sqlitesimpledelphi連接SQLite數(shù)據(jù)庫及中文亂碼問題的解決 http://hi.baidu.com/2356/blog/item/4a5549366d94afd6a3cc2bc7.html sqlitesimpledelphi修正以支持Unicode,Delphi 2010 測試通過 http://hi.baidu.com/2356/blog/item/236ceb2455f2520c4c088db2.html
SQLite的數(shù)據(jù)庫操作其實和常規(guī)的數(shù)據(jù)庫操作流程是一樣的: 1。連接數(shù)據(jù)庫。 2。構(gòu)造SQL語句并執(zhí)行 3。對于SELECT語句,可以獲取查詢結(jié)果 4。數(shù)據(jù)庫使用完畢之后,關(guān)閉數(shù)據(jù)庫
這里說明一下,下面所介紹的函數(shù)不會涵蓋所有的API函數(shù),畢竟SQLite針對同一個功能點提供了不同的API函數(shù),主要表現(xiàn)在參數(shù)和配置功能上,有需要深入了解的朋友可以參考官方的文檔。
1。打開數(shù)據(jù)庫: API函數(shù): int sqlite3_open( const char *filename, /* 數(shù)據(jù)庫文件路徑(UTF-8編碼) */ sqlite3 **ppDb /* 輸出: SQLite 數(shù)據(jù)庫句柄 */ ); int sqlite3_open16( const void *filename, /* 數(shù)據(jù)庫文件路徑(UTF-16) */ sqlite3 **ppDb /* 輸出: SQLite 數(shù)據(jù)庫句柄 */ ); 如果調(diào)用成功會返回SQLITE_OK,否則返回錯誤碼。
2。構(gòu)造SQL語句,這里就不多說了,這和SQLite本身無關(guān),可以根據(jù)需要使用適當(dāng)?shù)姆椒?gòu)造即可,注意傳給SQLite函數(shù)的時候,字符串編碼要記得轉(zhuǎn)換為UTF8/UTF16
3。執(zhí)行SQL語句。 在SQLite中執(zhí)行SQL語句比較簡單的方法是調(diào)用函數(shù): int sqlite3_exec( sqlite3*, /* 打開的數(shù)據(jù)庫句柄 */ const char *sql, /* UTF8編碼的SQL語句 */ int (*callback)(void*,int,char**,char**), /* 回調(diào)函數(shù),對于SELECT語句返回的結(jié)果處理在回調(diào)函數(shù)中進行 */ void *, /* 傳遞給回調(diào)函數(shù)的參數(shù) */ char **errmsg /* 相關(guān)錯誤信息 */ );
其實sqlite3_exec只是封裝了sqlite3_prepare、sqite3_step(即SQL中的預(yù)編譯技術(shù))的,主要目的是為使用者提供方便,筆者個人覺得使用后者會更加好一點,這里先做一下總結(jié):
int sqlite3_prepare( sqlite3 *db, /* 打開的數(shù)據(jù)庫句柄 */ const char *zSql, /* UTF8編碼的SQL語句,可以參數(shù)化 */ int nByte, /* SQL語句的字節(jié)長度,可以傳遞-1,即字符串以\0結(jié)尾 */ sqlite3_stmt **ppStmt, /* 輸出:預(yù)編譯之后的SQL語句句柄 */ const char **pzTail /* 輸出: 指向zSql緩沖區(qū)中跳過有效SQL字符串的第一個字節(jié) */ );
int sqlite3_prepare_v2( sqlite3 *db, /* 打開的數(shù)據(jù)庫句柄 */ const char *zSql, /* UTF8編碼的SQL語句,可以參數(shù)化 */ int nByte, /* SQL語句的字節(jié)長度,可以傳遞-1,即字符串以寬字符\0結(jié)尾 */ sqlite3_stmt **ppStmt, /* 輸出: 預(yù)編譯之后的SQL語句句柄 */ const char **pzTail /* 輸出: 指向zSql緩沖區(qū)中跳過有效SQL字符串的第一個字節(jié) */ );
int sqlite3_prepare16( sqlite3 *db, /* 打開的數(shù)據(jù)庫句柄 */ const void *zSql, /* UTF16編碼的SQL語句,可以參數(shù)化 */ int nByte, /* SQL語句的字節(jié)長度,可以傳遞-1,即字符串以寬字符\0結(jié)尾 */ sqlite3_stmt **ppStmt, /* 輸出: 預(yù)編譯之后的SQL語句句柄 */ const void **pzTail /* 輸出: 指向zSql緩沖區(qū)中跳過有效SQL字符串的第一個字節(jié) */ );
int sqlite3_prepare16_v2( sqlite3 *db, /* 打開的數(shù)據(jù)庫句柄 */ const void *zSql, /* UTF16編碼的SQL語句,可以參數(shù)化 */ int nByte, /* SQL語句的字節(jié)長度,可以傳遞-1,即字符串以寬字符\0結(jié)尾 */ sqlite3_stmt **ppStmt, /* 輸出: 預(yù)編譯之后的SQL語句句柄 */ const void **pzTail /* 輸出: 指向zSql緩沖區(qū)中跳過有效SQL字符串的第一個字節(jié) */ );
其中帶參數(shù)的SQL語句可以這樣定義參數(shù): NNN :VVV @VVV $VVV 參數(shù)編號從1開始,例如:INSERT into db values(?1, ?2)
v2版本函數(shù)時SQLite根據(jù)需要添加的增強函數(shù),新的程序推薦使用v2版本函數(shù),只需與原來函數(shù)的區(qū)別,可以參考官方原文
int sqlite3_step(sqlite3_stmt*); 執(zhí)行一次預(yù)編譯SQL語句,在這之前,如果SQL是參數(shù)化的,可以調(diào)用sqlite3_bind來綁定數(shù)據(jù),int、string、blob等等 如果執(zhí)行成功會返回SQLITE_DONE,如果查詢有結(jié)果會返回SQLITE_ROW,并可以通過API獲取結(jié)果中的第一行數(shù)據(jù),需要獲取下一行數(shù)據(jù)可以再次調(diào)用sqlite3_step直到返回SQLITE_DONE表示后面沒有數(shù)據(jù)了 如果需要重新對預(yù)編譯的SQL綁定數(shù)據(jù)并執(zhí)行,需要先reset一下,然后再調(diào)用step,即函數(shù): int sqlite3_reset(sqlite3_stmt *pStmt);
下面是綁定數(shù)據(jù)到預(yù)編譯SQL語句的相關(guān)函數(shù): 以下函數(shù)的第一個參數(shù)指代預(yù)編譯的SQL句柄,第二個參數(shù)指代綁定的參數(shù)編號,對應(yīng)于參數(shù)化的SQL語句中的參數(shù)編號:
int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); 該函數(shù)用于綁定二進制數(shù)據(jù)BLOB,其中最后一個參數(shù)是一個回調(diào)函數(shù),當(dāng)成功綁定數(shù)據(jù)后,會被調(diào)用,一般用于自動釋放對應(yīng)的緩沖區(qū)
int sqlite3_bind_double(sqlite3_stmt*, int, double); 該函數(shù)綁定double浮點數(shù)
int sqlite3_bind_int(sqlite3_stmt*, int, int); 該函數(shù)綁定int整數(shù)
int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); 該函數(shù)用于綁定具有64位長度的整數(shù),對應(yīng)于C中的long long結(jié)構(gòu),由于一個int的范圍可能無法滿足超大數(shù)據(jù)量的要求,所以SQLite也支持64位整數(shù),畢竟SQLite官方聲稱SQLite是支持最大2T的數(shù)據(jù)的
int sqlite3_bind_null(sqlite3_stmt*, int); 該函數(shù)綁定一個空數(shù)據(jù)到指定列
int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); 該函數(shù)綁定一段字符串,源字符串是UTF8編碼的
int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); 該函數(shù)綁定一段字符串,源字符串是UTF16編碼的
int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); 該函數(shù)綁定以SQLite結(jié)構(gòu)sqlite3_value存儲的通用數(shù)據(jù),其中sqlite3_value可以是上述的所有類型,此函數(shù)不太常用
int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); 該函數(shù)綁定指定大小的全零BLOB數(shù)據(jù)
3。獲取SQL查詢結(jié)果 對于SELECT語句,還需要能夠獲取結(jié)果。上面也提到調(diào)用sqlite3_step之后,對于有結(jié)果的查詢會返回第一行結(jié)果,這時可以通過API函數(shù)獲取當(dāng)前行的指定字段結(jié)果:
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); 該函數(shù)以BLOB數(shù)據(jù)格式獲取對應(yīng)列的數(shù)據(jù),BOLB長度使用sqlite3_column_bytes獲取
int sqlite3_column_bytes(sqlite3_stmt*, int iCol); int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); 該函數(shù)可以用于返回BLOB和字符串的字節(jié)長度。對于BLOB,兩個函數(shù)效果是一樣的,但是對于字符串sqlite3_column_bytes返回的是UTF8編碼的字符串長度,而sqlite3_column_bytes16返回的是UTF16編碼的字符串長度,其間會做必要的字符串格式轉(zhuǎn)換
double sqlite3_column_double(sqlite3_stmt*, int iCol); 該函數(shù)返回double數(shù)據(jù)列
int sqlite3_column_int(sqlite3_stmt*, int iCol); 該函數(shù)返回int數(shù)據(jù)列
sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); 該函數(shù)返回64位整數(shù),即long long數(shù)據(jù)
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); 該函數(shù)返回字符串,其中sqlite3_column_text輸出的字符串使用UTF8編碼
sqlite3_column_text16使用UTF16編碼 int sqlite3_column_type(sqlite3_stmt*, int iCol); 該函數(shù)返回對應(yīng)列的數(shù)據(jù)類型
sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); 該函數(shù)以sqlite3_value結(jié)構(gòu)體返回數(shù)據(jù)
上面是根據(jù)列ID來獲取對應(yīng)的列數(shù)據(jù)的,如果想通過列名稱獲取列數(shù)據(jù),則需要將列名稱轉(zhuǎn)換為對應(yīng)的列ID,可以使用下面的函數(shù): const char *sqlite3_column_name(sqlite3_stmt*, int N); const void *sqlite3_column_name16(sqlite3_stmt*, int N); 該函數(shù)返回對應(yīng)列的名稱
4。關(guān)閉數(shù)據(jù)庫
int sqlite3_close(sqlite3 * db); 使用該函數(shù)可以關(guān)閉數(shù)據(jù)庫
好了,基本的調(diào)用流程就這么些了,看完這篇文章,應(yīng)該能夠完成基本的數(shù)據(jù)讀寫操作了,至于其他的高級操作,有興趣的朋友可以登錄SQLite官方網(wǎng)站查看,這里就不在本文多說了。
|