iOS開發之SQLite-C語言接口規范(一)——Ready And Open Your SQLite


  為什么要搞一搞SQLite的C語言接口規范呢? 因為在做iOS開發中難免會遇到操作數據庫的情況,你可以使用第三方的FMDB等,或者使用CoreData。但我們還是有必要去搞清楚如何去使用SQLite的C語言接口來操作SQLite數據庫的。從今天開始就給大家結合實例詳細的搞一搞SQLite的C語言接口。關於CoreData的東西請看之前的博客《IOS開發之表視圖愛上CoreData》。

  如果英文好的小伙伴呢,你可以不聽我啰嗦,直接官網走起:http://www.sqlite.org 上面的東西是應有盡有,你可以下載資源如SQLite的Shell, 上面還有好多的學習資源。不過前提是英文不能太Low呢。之前看過幾本iOS開發的書籍,也包括某某出版社出版的《精通iOS開發》,雖然網上評價不錯,但看書的時候總是不來感。大部分書上介紹的SQLite, 講的太淺,只是羅列代碼,接口參數是什么意思,為什么這么寫都沒講。看書看的不爽了,就到官網上找找安慰吧,果不其然,眼前一亮。就寫幾篇博客好好的總結一下。

  一、准備SQLite測試工程和所需工具

    1. 准備一個已經引入動態鏈接庫libsqlite3.0.dylib的iOS單視圖工程(當然,看你心情,你也可以創建一個控制台工程,這不是重點)。

    2. 准備一個SQLite可視化的管理工具,我用的是SQLiteManager, 當然你可以選擇你用着順手的管理工具(自行百度吧)。當然如果你是初學者,並想“自殘”一下話,可以從官網上Download一個叫做sqlite-shell的東西,用純命令行去管理你的SQLite數據庫。其實如果習慣了,用純命令還是用着比較爽的,畢竟可以用來裝13不是么! SQLite官網上有詳細的Shell操作命令:如何去創建數據庫,如何創建表等一系列的操作,今天不做贅述。(如果你之前搞過MySQL, Oracle等,應該對命令行操作數據庫再熟悉不過了)。

    3. 你可以通過SQLiteManager來創建一個數據庫插入一些測試數據,以備在我們的測試工程中進行使用。或者你可以懶一些,直接從網上Download一個現成的SQLite數據庫進行操作使用(我下載了一個叫做Cars.sqlite文件來進行測試,數據庫的表結構及數據如下所示)。

 

  二、打開你的數據庫

    1.把准備好的測試SQLite數據庫引入到我們的測試工程中。

    2.通過NSBundle加載我們的數據庫資源

    //獲取Sqllite文件的路徑
    NSString *sqlPath = [[NSBundle mainBundle] pathForResource:@"Cars" ofType:@"sqlite"];

 

    3.因為是C語言接口,參數所用的字符串都是C語言中的字符串,所以呢得把字符串轉成C語言中的字符串吧(也就是C語言中char類型的指針)

    //把路徑轉成C字符串
    const char * filePath = [sqlPath UTF8String];

 

    4.你需要定義一個sqlite3結構體類型的指針變量,打開數據庫后可以獲取這個sqlite3結構體指針的值,並賦值給之前對應的指針變量,然后就可以通過該sqlite3結構體指針變量來操作數據庫。下面定義了一個sqlite3結構體類型的指針變量,然后把該指針變量的地址傳給sqlite3_open()函數,函數參數傳入的引用,在C語言中就可以得到數據庫操作指針。為了便於理解,可以把sqlite3結構體當做一個類,而sqlite3結構體的指針可以看做是類的對象。

    sqlite3 * database;
    
    //打開數據庫
    int result = sqlite3_open(filePath, &database);

 

   通過上述步驟就可以獲取到操作數據庫的結構體指針,sqlite3_open()函數,第一個參數就是C字符串格式的數據庫文件的路徑,第二個參數就是結構體指針的地址,用於獲取操作數據庫的句柄。該函數有一個int類型的返回值(0-101),這些返回值對應着不同的鏈接狀態。0代表着成功,其余見下圖:

    if (result == SQLITE_OK) {
        NSLog(@"連接成功");
    } else {
        NSString *error = [NSString stringWithFormat:@"錯誤結果代碼:%d", result];
        NSLog(@"%@", error);
    }

 

    

    sqlite3_open()就是一個構造函數, 另外還有sqlite3_open16()和sqlite3_open_v2(), 他們的功能都是打開一個新的數據庫的連接,所需參數如下所示。這些構造函數可以通過數據庫文件名稱參數來連接一個數據庫。如果文件名參數是UTF-8編碼格式的, 可以調用sqlite3_open()和sqlite3_open_v2(),   那么如果文件參數是 UTF-16編碼的話就調用構造函數sqlite3_open16()。第二個參數就是返回的數據庫操作句柄的指針地址。

    由下方的圖可以看出sqlite3_open_v2()比sqlite3_open()多了兩個參數,一個是int flags, 一個是const char *zVfs。 sqlite3_open_v2()的用法和sqlite3_open()類似,可以說前者是后者的加強版。sqlite3_open()是以前的舊方法,而sqlite3_open_v2()是后來改進的方法。

    參數flag,不同的值代表着打開數據庫后可以獲取的不同操作,類似於數據庫的操作權限,下方是flag的值代表的操作權限。

    SQLITE_OPEN_READONLY 數據庫是只讀模式打開。如果數據庫不存在,則返回一個錯誤。

    SQLITE_OPEN_READWRITE 數據庫以讀寫的模式打開, 如果文件被操作系統設置為保護模式,那么就為只讀模式。在這兩種情況下的數據庫必須已經存在,否則會返回一個錯誤。

    SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE 數據庫以讀寫的模式打開, 如果數據庫不存在,就創建一個。使用sqlite3_open()和sqlite3_open16()連接數據庫時,默認的就是這種行為。

    如果sqlite3_open_v2()的第三個參數不包含上述三種結合中的一個的話,那么數據庫的連接權限是未定義的。也就是說數據庫不知道是讀還是寫,還是創建,所以操作數據庫就沒有意義了,所以上面必須選擇一個參與“與”運算。

    SQLITE_OPEN_NOMUTEX 只要單線模式下沒有設置編譯的起始時間,就會在多線程模式下進行數據庫的連接。

    SQLITE_OPEN_FULLMUTEX 在序列化的線程模式(在此模式中,SQLite能無約束地在多線程中安全使用)打開數據庫連接,除非在編譯時或者單線程之前選擇起始時間。

    SQLITE_OPEN_SHAREDCACHE 可以使數據庫連接適當的使用共享緩存模式,無論是否使用sqlite3_enable_shared_cache()啟用共享緩存。

    SQLITE_OPEN_PRIVATECACHE 導致數據庫連接不使用共享緩存模式,即使共享緩存模型可用。

 

    sqlite3_open_v2()第四個參數是sqlite3_vfs對象的名稱,它定義了操作系統接口應該使用新的數據庫連接。如果第四個參數是一個nil的話,那么就會使用默認sqlite3_vfs對象。下方是結構體sqlite3_vfs的具體內容:

 

    vfs: sqlite3_vfs對象的實例定義了一個SQLite核心和底層操作系統間的接口。“vfs”對象的名稱代表“虛擬文件系統”。關於VFS的詳解內容在這里:https://www.sqlite.org/vfs.html 有興趣的小伙伴可以好好的搞一下。如果以后有時間的話在好好的介紹一下VFS。今天就不做過多的贅述了。第四個參數傳入nil就會使用默認的sqlite3_vfs默認對象。

    關於VFS和sqlite3_vfs結構體的東西,如果以后有時間,在單獨拿出來搞搞。了解VFS的結構和模式還是很有必要的。ok~今天打開並連接數據庫,關於如何去通過接口去操作數據庫就留在以后的博客中介紹吧。

    用到的數據庫和sqliteAPI代碼GitHub分享地址:https://github.com/lizelu/SQLiteResource

    在博客的最后呢,給出簡單封裝的打開數據庫的方法:

 1 /*******************************
 2  *功能:打開數據庫
 3  *參數:databaseName -- 數據庫名稱
 4  *返回:數據庫對象(sqlite3對象)
 5  *******************************/
 6 + (sqlite3 *) openDatabaseWithName: (NSString *)databaseName{
 7     
 8     //獲取Sqllite文件的路徑
 9     NSString *sqlPath = [[NSBundle mainBundle] pathForResource:databaseName ofType:@"sqlite"];
10     
11     //把路徑轉成C字符串
12     const char * filePath = [sqlPath UTF8String];
13     
14     sqlite3 * database;
15     
16     //打開數據庫
17     int result = sqlite3_open(filePath, &database);
18     
19     if (result == SQLITE_OK) {
20         return database;
21     }
22     
23     return nil;
24 
25 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM