如果沒有sqlite的基礎,我們隻是從android封裝的sqlite api去學習的話,難免思路會受到限制。是以,我們還是需要老老實實從頭開始學習sqlite.
當我們有一身的sqlite武功之後,再去看android的封裝,就能更清楚如何發揮sqlite的特長。
sqlite的核心隻有一個c檔案,通路的db也存在一個檔案當中。是以,我們完全可以把它嵌入到另外一個程式中。
在mac上,可以通過homebrew來安裝。安裝之後,我們就可以用sqlite3的api來寫代碼了。
我們找個網上找到的最簡單的打開關閉sqlite資料庫的例子:
我們先不管它是什麼意思,先編譯一下試試:
然後運作一下吧,需要本地有個叫contacts.db的資料庫。
輸出為:
從上面的例子,我們可以學習到兩個容易了解的api: sqlite3_open和sqlite3_close.
有了能運作的環境之後,我們就來看看sqlite資料庫引擎的結構吧:

從這張官方圖上,我們可以看到,除了工具和測試代碼之外,sqlite的核心部分分為三部分:核心,編譯器和後端。
核心部分就是對sql指令的處理的部分,它通過編譯器來編譯成vdbe(virtual database engine)能執行的代碼。
後端是真正對資料庫進行操作的部分,包括b-樹的查找結構等。
喜歡劃重點的同學注意啦,重點來了:調用sqlite3資料庫的代碼優化的第一個點就是将編譯好的位元組碼儲存起來,下次用的時候直接調用。
這麼重要的功能,sqlite3 api中當然有提供,這就是後面我們會大量學習使用的sqlite3_prepare和sqlite3_prepare_v2函數。
android對此也有同樣的封裝,提供了sqlitestatement來實作預編譯代碼的儲存。
有同學問了,我的sql語句并不是一成不變的,語句中的參數經常改變,這樣的話,編譯出來的代碼就沒有用了啊?
這在sqlite3的設計中當然是有考慮到的,編譯好的語句,是可以支援參數的。我們首先使用sqlite3_prepare_v2編譯,然後再通過sqlite3_bind_函數來綁定參數。下次如果換了參數,先調用sqlite3_reset清除掉綁定資訊,然後再重新用sqlite3_bind_來做綁定新參數,就可以了。
一個調用sqlite3實作資料庫操作的功能可以用下面的步驟來套用:
根據業務需求,構造sql語句
調用sqlite3_prepare_v2函數來編譯sql語句
如果有參數,調用sqlite3_bind_*函數來綁定參數
調用sqlite3_step函數來執行一次sql操作,直至所有操作都完成
下次再使用第2步編譯出來的語句時,調用sqlite3_reset函數清理參數。然後重複第3步的操作
最後,調用sqlite3_finalize來銷毀預編譯語句
下面我們直接開始實操,首先先舉個select的例子。
我們以android中聯系人資料庫為例,取其中的calls表的簡化版:
雖然字段很多,我們就關注id和号碼就好。
我們先來一半,我們選_id和number這兩列,然後看看傳回的資料中是不是兩列:
核心代碼如下:
完整版的代碼,便于大家實驗:
下面我們直接調用sqlite3_step去讀每一條記錄,增加下面一段:
如果sqlite3_step傳回的結果是sqlite_row,說明這一次執行取到了一條符合條件的記錄。每次取一條記錄。
完整代碼如下:
輸出如下例:
上面的例子是針對查詢語句的,我們再舉個非查詢語句的例子。比如我們試個插入的例子。
輸出如下:
上面,我們就查詢和非查詢兩種情況,學習了如何使用sqlite3的api。
剩下的工作主要就是構造sql語句以及處理傳回結果了。