標籤:
資料庫的相關知識我就不去說明了,畢竟只要會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