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