標籤:
使用步驟
1. 引入標頭檔:在工程的 Build Phases 下將要用到的 frameworks 和 libraries 添加。中我已經將要用的 sqlite3 添加到工程。
2. 指定資料庫儲存路徑:資料庫一般都是儲存在沙箱根目錄下地 Documents 檔案夾下,在指定路徑的時候,要將資料庫的名稱也寫上
NSString *sandBox = NSHomeDirectory();NSString *filePath = [sandBox stringByAppendingPathComponent:@"Documents/db_student.sqlite"]; // 建立的資料庫名是 db_student.sqlite
3.開啟資料庫
3.1 首先將 OC 的路徑字串轉化為 C 的字串
const char * path = [filePath UTF8String];
3.2 開啟資料庫
sqlite3_open(path, &_db);
需要知道的是這句代碼有兩個作用:
1)如果資料庫不存在,則建立資料庫,然後開啟;
2)如果資料庫已經存在,則直接開啟資料庫。
int sqlite3_open( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb /* OUT: SQLite db handle */);
這是這句代碼的函式宣告:從中可以看到
第一個參數要求的是 資料庫的檔案名稱,並且是經過 UTF-8 轉化過的 C 字串;
第二個參數要求的是 sqlite3 類型的雙指標,所以傳遞過來的是一個地址指標;
最後一點:如果成功開啟資料庫,則返回一個值 SQLITE_OK
#define SQLITE_OK 0 /* Successful result */
4.建立表
4.1 建立表的 sql 語句:注意是 C 語言的字串而不是 OC 類型的字串
const char *sql = "create table if not exists tb_student (id integer primary key,sex boolean,name text)";
4.2 執行 DDL 語句,只有是 DDL 語句時才調用 exec 函數
int sqlite3_exec(sqlite3*, const char *sql, int (*callback)(void*,int,char**,char**), void *, char **errmsg);/* 第一個參數:資料庫的變數,一個已經開啟i資料庫 第二個參數:建立表的語句 第三個參數:回呼函數,即語句執行完要執行的函數,通常填寫 nil 第四個參數:回呼函數的第一個參數;通常填 nil 第五個參數:錯誤資訊;可以填 nil;注意是雙指標*/sqlite3_exec(_db, createSql, NULL, NULL,NULL); //所以建立表的語句可以這樣寫這句代碼同樣有個傳回值,返回 SQLITE_OK 表示表成功建立。
5.對資料表進行增、刪、改、查的操作
5.1 有預留位置的 sql 語句
添加 insert into tb_student (name, sex) values (?, ?);
1) 請不要被語句裡的 ? 給嚇到了,在這裡它的作用是預留位置的作用,表示這裡需要一個值,而這個值不是給定的,而是一個不確定值,例如可以根據文字框獲得。
當然了,如果直接使用這種語句操作資料表,那是萬萬不能的,為啥丫,人家不認識你唄,也許你就說了,那我直接寫成確定值,這樣總可以吧!答案依然還是不行,這個我也覺得很坑哪([email protected][email protected]=)
那麼要怎麼辦呢 —— 將 sql 語句轉化為 sqlite3_stmt 類型(現在都一家人了,總不能還不待見我吧)
sqlite3_stmt * stmt = nil; sqlite3_prepare_v2(_db, sql, -1, &stmt, NULL) //不要小看這兩句代碼:把字串類型的 sql 語句,轉化為 stmt 類型;只有轉化後,才能把問號(?)替換為對應的資料,注意不管 sql 語句裡面有沒有問號,都要進行轉化成這種 stmt 類型
下面這個 C 函數就是上面第二句代碼的原型
/* 第一個參數:資料庫變數 第二個參數:sql語句 第三個參數:字串的長度;-1表示系統計算長度; 第四個參數:語句轉化之後的儲存位置的指標; 第五個參數:超出指定長度的資料的存放位置;通常填null;*/int sqlite3_prepare_v2(sqlite3 *db,const char *zSql, int nByte, sqlite3_stmt **ppStmt, const char **pzTail);
2)接下來的共走就是將語句裡面的 ?給替換掉了:這個就要根據你的欄位類型來決定使用哪個方法了,如果是字串類型(即 text 類型), 就使用函數
/* 第一個參數:stmt結構 第二個參數:替換哪一個問號;從1開始; 第三個參數:替換的內容 第四個參數:字串的長度,- 1 表示系統計算長度 第五個參數:回呼函數;通常寫null*/int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*))
有傳回值 SQLITE_OK,表示轉化成功
則調用的時候
sqlite3_bind_text(stmt, 1, name, -1, NULL); // name 是通過文字框擷取的內容
如果是 int 類型或 boolean 類型則簡單多了
sqlite3_bind_int(stmt, 2, sex); // sex 是同過文字框獲得的內容
3)執行 sqlite3_step(stmt)
執行成功的時候返回 SQLITE_DONE,所以可以通過傳回值來判斷語句是否成功執行
4)當插入的動作執行完成的時候,不要忘記將 stmt 銷毀
sqlite3_finalize(stmt);
5)關閉資料庫
插入完成,不再進行其他動作時,關閉資料庫
sqlite3_close(_db);
5.2 沒有預留位置的查詢語句
即使沒有 sql 語句中沒有預留位置,也要將 sqll 語句轉化為 stmt 類型
5.3 查詢語句
查詢語句有兩個不同的地方
1)查詢成功的傳回值不同 SQLITE_ROW
2)啟動並執行機制也有所不同:在將表中所有資料遍曆完成之前,一直在進行查詢操作,每查詢到一條合格記錄,就返回一個 SQLITE_ROW,所以可以用這個特性將表中合格資料都取出來。
while (sqlite3_step(stmt) == SQLITE_ROW){ /* 第一個參數:stmt 第二個參數:取哪一列的值 ;從0開始 */ int ID = sqlite3_column_int(stmt, 0); int sex = sqlite3_column_int(stmt, 2); const unsigned char *cName = sqlite3_column_text(stmt, 1); NSString *name = nil; if (cName != NULL) { name = [NSString stringWithUTF8String:(const char *)cName]; } NSLog(@"_____ID: %d ____name: %@ _____ sex: %d", ID, name, sex);}
sqlite 資料庫的初級使用