Objective-C訪問SQLite

來源:互聯網
上載者:User

標籤:

資料庫的相關知識我就不去說明了,畢竟只要會sql語言的人就大家都一樣。

  本案例是在Xcode7.2環境下建立的single view application進行示範操作。

  首先第一點,為什麼要使用sqlite3?   

  在iOS的編程中,毫無疑問接觸最多的就是介面的代碼編排和設計,資料的解析與放置,演算法的各種撓頭問題。。。   在資料的解析與放置這一塊,就會涉及到資料庫緩衝的操作,我們都知道,iOS手機編程是在手機端啟動並執行,你不能老是去伺服器端讀取資料啊,好,就算你不煩,手機也跑的起來,流量不要過啊,對於手機控或者應用使用者來說,流量就是生命,而且,如果總是去伺服器端讀取資料,對手機的運行速度也會有影響,畢竟有一個網路傳輸的過程,所以,為了讓使用者有一個更好的體驗,一般建議的做法是,將伺服器的資料進行下載,然後通過資料庫緩衝起來,這樣就不用每次每次的去請求伺服器資料了,如果在資料庫中有的資料,直接可以通過資料庫查詢得到,而省去了一次甚至多次的伺服器請求操作。而sqlite3就是提供了一種C語言的訪問資料庫的形式。之後我們的代碼會看到,其實sqlite3的文法可能比較難以理解,不過,我也會給大家來進行介紹的。      

  那麼第二點,使用sqlite3的好處是什麼?

  使用sqlite3的好處麼,除開文法的各種蛋疼之外,訪問的速度還是會比FMDB快一些的。而且,隨著一步步的匯總和總結,你可以清晰的知道每一句sqlite3的語句的作用,而不是使用封裝好了的語句,只要用就可以了,但是不知道是為什麼。我個人覺得,學習學習吧,還是要知其然,亦知其所以然這樣才能學的踏實。

第一步,引入 libsqlite3.tbd 靜態庫

第二步,在要使用 SQLite 的地方匯入庫主標頭檔 #import <sqlite3.h>

 

第三步,建立sqlite資料庫檔案

  * sqlite3提供的是一種訪問操縱資料庫的形式,那麼,如果想要使用sqlite3來訪問操縱資料庫,首先我們得先有個資料庫,下面就是使用代碼產生一個資料庫檔案。

// SQLite檔案名稱static NSString * const fileName = @"SQLite.sqlite";// 得到資料庫檔案地址,這是一個拼接的地址字串,是沙箱路徑下面的shop.sqlite檔案// 這個檔案名稱可以隨便取名字,尾碼最好是db啊或者sqlite這種,用來表示這是一個資料庫檔案NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]               stringByAppendingPathComponent:fileName];

  開啟資料庫連接,如果有就開啟,沒有就重新建立串連。

  * sqlite3_open是我們接觸到的第一條sqlite3語句,它的作用時開啟資料庫連接,如果有資料庫檔案就開啟它,沒有就重新建立資料庫,這個方法有一個枚舉的傳回值表示是否正常開啟了資料庫,我用int的變數status去接收了這個值,後面會進行判斷。  

  * sqlite3_open有兩個參數,第一個參數是資料庫檔案的路徑,第二個參數是一個資料庫的引用,即一個sqlite3 *類型的引用;

  * filePath.UTF8String: filename本身是oc的字串類型,但是sqlite3_open要求傳遞的是C類型的字串,所以,使用UTF8String將oc的字串類型轉換為C類型的字串

@interface ViewController (){    sqlite3 *_sqlite;}@end// 開啟資料庫連接,如果有就開啟,沒有就重新建立串連NSInteger state = sqlite3_open(filePath.UTF8String, &_sqlite);// 枚舉值SQLITE_OK代表成功的狀態if (state == SQLITE_OK)    NSLog(@"----- 開啟資料庫成功 -----");else    NSLog(@"----- 開啟資料庫失敗 -----");

  

第四步,建立資料庫表

  * 當我們開啟了資料庫連接的時候,表示在程式的沙箱路徑下已經建立了一個 SQLite.sqlite 的資料庫檔案,而這個資料庫裡現在什麼東西都沒有,我們需要建立一張資料庫表來存放資料。

  * sqlite3_exec 是我們接觸到的第二個sqlite3語句,這個語句用於執行除了查詢語句以外的其他語句.

      它有一個枚舉類型的傳回值,和 sqlite3_open 返回的枚舉值一致,這裡我並沒有使用變數儲存,因為我有其他形式來獲得建立表是否成功。

  * sqlite3_exec 需要傳遞5個參數,第一個參數是資料庫引用即 sqlite3 *_shop,第二個參數是要執行的sql語句,

      第三個參數是執行完sql語句後要執行的函數,第四個參數是執行完sql語句後要執行的函數的參數,第五個參數是執行完sql語句後的報錯資訊。

// 創表語句,IF NOT EXISTS防止建立重複的表,AUTOINCREMENT是自動成長關鍵字,real是數字類型const char *sql = "CREATE TABLE IF NOT EXISTS t_SQLite(id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL, price real)";//儲存錯誤資訊的變數char *errorMessage = NULL;sqlite3_exec(_sqlite, sql, NULL, NULL, &errorMessage);// 如果存在報錯資訊,代表語句執行失敗,比判斷枚舉值要更簡單一些if (errorMessage)    NSLog(@"----- 建立表失敗 -> errorMessage: %s -----", errorMessage);else    NSLog(@"----- 建立表成功 -----");

第五步,資料表操縱

  所謂的資料表操縱即是對資料表中資料的增刪改,也是最經常會使用到的功能。即執行insert, update, delete語句。

  (1)增

    * 註:這裡我在 Main.storyboard 裡面拖了兩個輸入框(UITextField)和一個按鈕(UIButton),並建立關聯

@interface ViewController (){    sqlite3 *_sqlite;}@property (weak, nonatomic) IBOutlet UITextField *nameField;@property (weak, nonatomic) IBOutlet UITextField *priceField;@end#pragma mark 增- (IBAction)addDataEvent:(UIButton *)sender {    NSString *name = [self.nameField.text stringByReplacingOccurrencesOfString:@" " withString:@""];    CGFloat price = self.priceField.text.floatValue;    // 拼接插入資料的sql語句    NSString *sql = [NSString stringWithFormat:@"INSERT INTO t_SQLite(name,price) VALUES(‘%@‘,%f)", name, price];    char *errorMessage = NULL;    sqlite3_exec(_sqlite, sql.UTF8String, NULL, NULL, &errorMessage);    if (errorMessage)        NSLog(@"----- 插入資料失敗 -> errorMessage: %s -----", errorMessage);    else        NSLog(@"----- 插入資料成功 -----");}

  

  (2)刪

    * 註:這裡我在 Main.storyboard 裡 新增按鈕下方拖放了一個輸入框(UITextField)和一個刪除按鈕(UIButton),並建立關聯

      這裡是以 id 為關鍵字進行定位到資料的,所以,這個 id 的值必須是已有的資料的 id 值

@interface ViewController (){    sqlite3 *_sqlite;}@property (weak, nonatomic) IBOutlet UITextField *nameField;@property (weak, nonatomic) IBOutlet UITextField *priceField;@property (weak, nonatomic) IBOutlet UITextField *lbl;@end#pragma mark - 刪- (IBAction)deleteDataEvent:(UIButton *)sender {    NSString *lbl = [self.lbl.text stringByReplacingOccurrencesOfString:@" " withString:@""];    // 拼接sql刪除語句    NSString *sql = [NSString stringWithFormat:@"DELETE FROM t_SQLite where id=%ld", lbl.integerValue];    char *error = NULL;    sqlite3_exec(_sqlite, sql.UTF8String, NULL, NULL, &error);    if (error)        NSLog(@"----- 刪除資料失敗 -> error: %s -----", error);    else         NSLog(@"----- 刪除資料成功 -----");}

  (3)改

    * 註:這裡我在 Main.storyboard 裡新拖了一個修改按鈕(UIButton),並建立關聯

      這裡是以 id 為關鍵字進行定位到資料的,所以,這個 id 的值必須是已有的資料的 id 值

#pragma mark - 改- (IBAction)updateDataEvent:(UIButton *)sender {    NSString *name = [self.nameField.text stringByReplacingOccurrencesOfString:@" " withString:@""];    NSString *price = [self.priceField.text stringByReplacingOccurrencesOfString:@" " withString:@""];    NSString *lbl = [self.lbl.text stringByReplacingOccurrencesOfString:@" " withString:@""];    // 拼接更新資料的sql語句    NSString *sql = [NSString stringWithFormat:@"update t_SQLite set name=‘%@‘,price=‘%@‘ where id=%@", name, price, lbl];    char *error = NULL;    sqlite3_exec(_sqlite, sql.UTF8String, NULL, NULL, &error);    if (error)        NSLog(@"----- 更新資料失敗 -> error: %s -----", error);     else        NSLog(@"----- 更新資料成功 -----");}

    大家可以觀察上面的三個方法,會發現除了sql語句的拼接不一樣以外,其他的地方几乎一模一樣,所以,增刪改的操作相對來說還是比較簡單的。

  (4)查

    * sqlite3_prepare_v2函數是準備要執行sql查詢的一個函數,可以當做這個函數就是用來做sql查詢之前的準備工作的,它也是返回一個枚舉作為準備工作的結果,SQLITE_OK則代表準備工作ok

    * sqlite3_prepare_v2需要傳入5個參數,第一個參數是資料庫引用即(sqlite3* _shop),第二個參數是要執行的sql語句,第三個參數是sql語句的長度,第四個參數是查詢結果stmt的引用,查詢完成後,查詢結果將會存入該引用,第五個參數是指向無法使用的部分的指標,一般不會用到,給NULL就可以了

    * sqlite3_step(stmt)函數將會執行查詢並且將查詢到的目前記錄存入到stmt(sqlite3_stmt * 類型)中

    * 第一次執行sqlite3_step(stmt)將會將表中的第一條資料存入到stmt中,第二次執行sqlite3_step(stmt)將會把表中的第二條記錄存入到stmt中

    * 也就是說,while(sqlite3_step(stmt)==SQLITE_ROW)將會一條一條的去讀取表中的記錄,而SQLITE_ROW枚舉判斷的是有讀取到資料行的情況

#pragma mark - 查- (void)inquiryData {    // 查詢sql語句    const char *sql = "select * from t_SQLite";    // stmt用來取出查詢結果    sqlite3_stmt *stmt = NULL;    NSInteger state = sqlite3_prepare_v2(_sqlite, sql, -1, &stmt, NULL);    // 準備成功,SQL語句正確    if (state == SQLITE_OK)        // 成功指向一條記錄        while (sqlite3_step(stmt) == SQLITE_ROW) {            // 封裝的實體            Shop *shop = [[Shop alloc] init];            //sqlite3_column_xxxx函數:它用來讀取資料行中不同類型的資料,該函數的傳回值就是讀取到得資料內容,該函數需要2個參數,
          第一個參數是存放資料的stmt,第二個參數是資料列下標 // 讀取stmt中儲存的第0列資料 shop.pid= sqlite3_column_int(stmt, 0); // 讀取stmt中儲存的第1列資料 const char *name = (const char*)sqlite3_column_text(stmt, 1); // 讀取stmt中儲存的第2列資料 const char *price = (const char*)sqlite3_column_text(stmt, 2); // 將C類型的字串轉換為oc類型的字串並儲存 shop.name = [NSString stringWithUTF8String:name]; // 將C類型的字串轉換為oc類型的字串並儲存 shop.price = [NSString stringWithUTF8String:price]; } else NSLog(@"----- 讀取資料失敗 -----");

對sqlite3的基本使用大致就這些,平時我們要用的也只是這些操作,其他的SQL操作正常情況下是不會涉及到。

接下來就是將上面的代碼重複的運用到你的項目中! 

附源碼地址: 源碼連結 密碼: 5xgm

Objective-C訪問SQLite

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.