iOS中的SQLLite
iPhone中支援通過sqlite3來訪問iPhone本地的資料庫。
具體使用方法如下
1:添加開發包libsqlite3.0.dylib
首先是設定專案檔,在項目中添加iPhone版的sqlite3的資料庫的開發包,在項目下的Frameworks點擊右鍵,然後選擇libsqlite3.0.dylib檔案。
2,代碼中的操作:
那麼接下來是代碼了。
1 首先擷取iPhone上sqlite3的資料庫檔案的地址
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@database_name];
2 開啟iPhone上的sqlite3的資料庫檔案
sqlite3 *database;
sqlite3_open([path UTF8String], &database);
3 準備sql文---sql語句
sqlite3_stmt *stmt;
const char *sql =
SELECT * FROM table_name WHERE pk=? and name=?;
sqlite3_prepare_v2(database,
sql, -1, &stmt, NULL);
4 邦定參數
// 邦定第一個int參數
sqlite3_bind_int(stmt, 1, 1);
// 邦定第二個字串參數
sqlite3_bind_text(stmt, 2, [title UTF8String], -1, SQLITE_TRANSIENT);
5 執行sql文
sqlite3_step(stmt);
6 釋放sql文資源
sqlite3_finalize(stmt);
7 關閉iPhone上的sqlite3的資料庫
sqlite3_close(database);
http://hi.baidu.com/clickto/blog/item/0c6904f787c34125720eec87.html
以下示範一下使用sqlite的步驟,先建立一個資料庫,然後查詢其中的內容。2個重要結構體和5個主要函數:
sqlite3 *pdb, 資料庫控制代碼,跟檔案控制代碼FILE很類似
sqlite3_stmt *stmt, 這個相當於ODBC的Command對象,用於儲存編譯好的SQL語句
sqlite3_open(), 開啟資料庫
sqlite3_exec(), 執行非查詢的sql語句
sqlite3_prepare(), 準備sql語句,執行select語句或者要使用parameter bind時,用這個函數(封裝了sqlite3_exec).
Sqlite3_step(), 在調用sqlite3_prepare後,使用這個函數在記錄集中移動。
Sqlite3_close(), 關閉資料庫檔案
還有一系列的函數,用於從屬記錄集欄位中擷取資料,如
sqlite3_column_text(), 取text類型的資料。
sqlite3_column_blob(),取blob類型的資料
sqlite3_column_int(), 取int類型的資料
PreparedStatement方式處理SQL請求的過程
特點:可以綁定參數,產生過程。執行的時候像是ADO一樣,每次返回一行結果。
1. 首先建立statement對象:
int sqlite3_prepare(
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nBytes, /* Length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
2. 綁定過程中的參數(如果有沒有確定的參數)
int sqlite3_bind_xxxx(sqlite3_stmt*, int, ...);
第二個int型別參數-表示參數的在SQL中的序號(從1開始)。
第三個參數為要綁定參數的值。
對於blob和text數值的額外參數:
第四參數是字串(Unicode 8or16)的長度,不包括結束''。
第五個參數,類型為void(*)(void*),表示SQLite處理結束後用於清理參數字串的函數。
沒有進行綁定的未知參數將被認為是NULL。
3. 執行過程
int sqlite3_step(sqlite3_stmt*);
可能的傳回值:
*SQLITE_BUSY: 資料庫被鎖定,需要等待再次嘗試直到成功。
*SQLITE_DONE: 成功執行過程(需要再次執行一遍以恢複資料庫狀態)
*SQLITE_ROW: 返回一行結果(使用sqlite3_column_xxx(sqlite3_stmt*,, int iCol)得到每一列的結果。
再次調用將返回下一行的結果。
*SQLITE_ERROR: 運行錯誤,過程無法再次調用(錯誤內容參考sqlite3_errmsg函數傳回值)
*SQLITE_MISUSE: 錯誤的使用了本函數(一般是過程沒有正確的初始化)
4. 結束的時候清理statement對象
int sqlite3_finalize(sqlite3_stmt *pStmt);
應該在關閉資料庫之前清理過程中佔用的資源。
5. 重設過程的執行
int sqlite3_reset(sqlite3_stmt *pStmt);
過程將回到沒有執行之前的狀態,綁定的參數不會變化。
擷取檔案的路徑
- (NSString *)getDataBasePath{ NSString* path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; NSString* filePath = [path stringByAppendingPathComponent:@database.db]; // NSString* filePath = [NSHomeDirectory() stringByAppendingPathComponent:@Document/database.db]; return filePath;}
開啟資料庫
- (void)openDatabase{ //1、擷取檔案路徑 NSString* filePath = [self getDataBasePath]; //2、oc字串--->c字串 const char * filename = [filePath UTF8String]; //3、開啟資料庫 :如果資料庫檔案存在直接開啟,不存在,系統會在該路徑下建立同名檔案. //1‘ 資料庫檔案名 c字串 //2‘ 資料庫物件 sqlite3 **ppDb int rc = sqlite3_open(filename,&_database); //SQLITE_OK 操作成功 //資料庫開啟失敗 if (rc != SQLITE_OK) { //關閉資料庫: sqlite3_close(_database); //插入斷言:如果條件運算式的值為NO,程式崩潰,會輸出參數2的值 //1'<#condition#>條件判斷 //2'desc 程式崩潰後輸出的字串 NSAssert(NO, @資料庫開啟失敗,請檢查檔案路徑); }else{ NSLog(@資料庫開啟成功); } }
資料表建立
- (IBAction)createTable:(id)sender{ //1、開啟資料庫 [self openDatabase]; //2、建立表的SQL語句: ContactTable NSString* createSql = @CREATE TABLE ContactTable (name TEXT,phone TEXT) ; char* errmsg = nil; //3、執行建立表的sql語句: //1' 資料庫物件 //2' SQL語句 -C字串 將OC字串轉換成C字串 //3' C語言的回呼函數:類似於代理方法,NULL //4' 回呼函數中的第一個參數: NULL //5' 執行的錯誤資訊 int rc = sqlite3_exec(_database, [createSql UTF8String], NULL, NULL, &errmsg); //SQLITE_OK 執行成功 //表的建立失敗 if (rc != SQLITE_OK) { NSLog(@資料表建立失敗); }else{ NSLog(@資料庫表建立成功); } //使用完關閉資料庫 sqlite3_close(_database); }
插入資料
- (IBAction)insertData:(id)sender{ //1.開啟資料庫 [self openDatabase]; //2.SQL語句:?代表欄位內容的預留位置,有幾個欄位需要幾個? NSString* insertSql = @INSERT INTO ContactTable VALUES(?,?); //準備一個緩衝區 結構體 sqlite3_stmt * stmt = nil; //3、準備插入資料:將sql語句轉化成位元組碼,並不執行語句 //1' 資料庫物件 //2' sql語句c字串 //3' sql語句的長度:strlen函數擷取strlen([insertSql UTF8String],此處一般填寫-1,代表從sql語句的第一個字元 讀取到 第一個終止符;讀取完整地sql語句 //4' 語句的緩衝區 //5' pzTail:如果參數3指定的不是完整地sql語句,此參數會保留剩餘的部分;NULL int rc = sqlite3_prepare_v2(_database, [insertSql UTF8String], -1, &stmt, NULL); //如果資料準備完成 :SQLITE_OK if (rc == SQLITE_OK) { //4、將內容綁定到緩衝區: //1' 指定的緩衝區 //2' 欄位索引:從1開始;預設每一條記錄都會添加一個ROWID //3' 欄位的值:c字串 //4' 字串的長度 //5' 函數指標:NULL NSString* name = @zhangsan; sqlite3_bind_text(stmt, 1, [name UTF8String], strlen([name UTF8String]),NULL); NSString* phone = @電話號碼; sqlite3_bind_text(stmt, 2, [phone UTF8String], strlen([phone UTF8String]), NULL); //5、執行sql語句,如果綁定過程發生錯誤,會將緩衝區的內容置空 int rc = sqlite3_step(stmt); //執行插入操作是否成功 //SQLITE_DONE:如果執行成功,表示插入一條記錄執行完畢,沒有下一條記錄 //SQLITE_ROW:執行一條記錄完成,還有下一條記錄 if (rc == SQLITE_DONE) { NSLog(@插入資料成功); }else{ NSLog(@插入資料失敗____%s,sqlite3_errmsg(_database)); } //6、釋放緩衝區 : 控制代碼 sqlite3_finalize(stmt); } //7、關閉資料庫 sqlite3_close(_database); }
刪除資料
- (IBAction)deleteData:(id)sender{ //1、開啟資料庫 [self openDatabase]; //2、sql語句 NSString* deleteSql = @DELETE FROM ContactTable WHERE name = 'zhangsan'; //3、緩衝區 sqlite3_stmt* stmt = NULL; //4、準備sql語句 int rc = sqlite3_prepare_v2(_database, [deleteSql UTF8String], strlen([deleteSql UTF8String]), &stmt, NULL); //5、準備完成, if (rc == SQLITE_OK) { //6、執行sql語句 if (sqlite3_step(stmt) == SQLITE_DONE) { NSLog(@資料刪除完成); } //7、釋放緩衝區 sqlite3_finalize(stmt); } //8、關閉資料庫 sqlite3_close(_database);}
修改資料
- (IBAction)upDateData:(id)sender{ //1.開啟資料庫 [self openDatabase]; //2.SQL語句// NSString* updateSql = @UPDATE ContactTable SET phone = '18909091234' WHERE name = 'zhangsan'; NSString* updateSql = @UPDATE ContactTable SET phone = '18909091234' WHERE ROWID = 1; //3.緩衝區 sqlite3_stmt* stmt = NULL; //4.準備sql int rc = sqlite3_prepare_v2(_database, [updateSql UTF8String], -1, &stmt, NULL); //5.準備完成 if (rc == SQLITE_OK) { //6.執行sql if (sqlite3_step(stmt) == SQLITE_DONE) { NSLog(@資料更新成功); }else{ NSLog(@資料更新失敗); } //7.釋放緩衝區 sqlite3_finalize(stmt); } //8.關閉資料庫 sqlite3_close(_database);}
查詢
- (IBAction)queryData:(id)sender{ //裝取出的每一條記錄 NSMutableArray* mArray = [NSMutableArray array]; //1.開啟資料庫 [self openDatabase]; //2.sql語句 NSString* querySql = @SELECT * FROM ContactTable; //3.準備一個緩衝區 sqlite3_stmt* stmt = NULL; //4.準備讀取資料: int rc = sqlite3_prepare_v2(_database, [querySql UTF8String], -1, &stmt, NULL); //5.準備完成 if (rc == SQLITE_OK) { //6.執行sql:如果有多條資料,或者不知道資料庫中有多少行資料,使用while迴圈執行 //如果執行完畢,返回SQLITE_DONE,不再走while語句;如果還有下一條資料,返回SQLITE_ROW,繼續進入while迴圈 while (sqlite3_step(stmt) == SQLITE_ROW) { //7.從緩衝區取資料: //1' 緩衝區 //2' 欄位索引: 從0開始 char* name = (char *)sqlite3_column_text(stmt, 0); char * phone =(char *)sqlite3_column_text(stmt, 1); //將C字串--->OC字串 NSString* nameStr = [[NSString alloc] initWithUTF8String:name];// [NSString stringWithUTF8String:name]; NSString* phoneStr = [[NSString alloc] initWithUTF8String:phone]; //每條記錄都有電話和姓名:放在數組中,一個資料代表一條記錄 [mArray addObject:nameStr]; [mArray addObject:phoneStr]; } //釋放緩衝區:寫在while迴圈外 sqlite3_finalize(stmt); } for (id object in mArray) { NSLog(@取出的資料為____%@,object); } //關閉資料庫 sqlite3_close(_database); }