數據庫-FMDB簡單實用

前言

FMDB是以OC的方式封裝了SQLite的C語言API,使用起來更加面向對象,省去了很多麻煩、冗餘的C語言代碼;對比蘋果自帶的Core Data框架,更加輕量級和靈活;提供了多線程安全的數據庫操作方法,有效地防止數據混亂;FMDB同時兼容ARC和非ARC工程,在編譯的時候會自動根據工程配置來調整相關的內存管理代碼。

使用方法

FMDB有三個主要的類

  • FMDatabase 表示一個單獨的SQLite數據庫。 用來執行SQLite的命令。
  • FMResultSet 表示FMDatabase執行查詢後的結果集
  • FMDatabaseQueue 如果你想在多線程中執行多個查詢或更新,你應該使用該類。這是線程安全的。

數據庫創建

通過指定SQLite數據庫文件路徑來創建FMDatabase對象

FMDatabase *db = [FMDatabase databaseWithPath:path];
if (![db open]) {
  NSLog(@"數據庫打開失敗!");
}

 

創建FMDatabase對象時參數爲SQLite數據庫文件路徑。該路徑可以是以下三種之一:

1、具體文件路徑

  • 該文件路徑無需真實存,如果不存在會自動創建。

2、空字符串@""

  • 表示會在臨時目錄創建一個空的數據庫,當FMDatabase 鏈接關閉時,數據庫文件也被刪除。

3、NULL

  • 會創建一個內存中臨時數據庫,當FMDatabase連接關閉時,數據庫會被銷燬

打開數據庫

在和數據庫交互 之前,數據庫必須是打開的。如果資源或權限不足無法打開或創建數據庫,都會導致打開失敗,返回BOOL類型

if (![db open]) {    
        [db release];   
        return;    
 }

 

執行更新

  • 一切不是SELECT命令的命令都視爲更新。這包括 CREATE, UPDATE, INSERT,ALTER,COMMIT, BEGIN, DETACH, DELETE, DROP, END, EXPLAIN, VACUUM, and REPLACE (等)。
    簡單來說,只要不是以SELECT開頭的命令都是UPDATE命令。
  • 執行更新返回一個BOOL值。YES表示執行成功,否則表示有那些錯誤 。你可以調用 -lastErrorMessage 和 -lastErrorCode方法來得到更多信息。

使用executeUpdate:方法執行更新

- (BOOL)executeUpdate:(NSString*)sql, ...
- (BOOL)executeUpdateWithFormat:(NSString*)format, ...
- (BOOL)executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments

 

示例

[db executeUpdate:@"UPDATE t_student SET age = ? WHERE name = ?;", @20, @"Jack"]

執行查詢

SELECT命令就是查詢,執行查詢的方法是以 -excuteQuery開頭的。

查詢方法

- (FMResultSet *)executeQuery:(NSString*)sql, ...
- (FMResultSet *)executeQueryWithFormat:(NSString*)format, ...
- (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray *)arguments

 

執行查詢時,如果成功返回FMResultSet對象, 錯誤返回nil. 與執行更新相當,支持使用 NSError**參數。同時,你也可以使用 -lastErrorCode和-lastErrorMessage獲知錯誤信息。

爲了遍歷查詢結果,你可以使用while循環。你還需要知道怎麼跳到下一個記錄。使用FMDB,很簡單實現,就像這樣:

FMResultSet *s = [db executeQuery:@"SELECT * FROM myTable"];   
while ([s next]) {   
    //retrieve values for each record   
}

你必須一直調用 -[FMResultSet next] 在你訪問查詢返回值之前,甚至你只想要一個記錄:
FMResultSet *s = [db executeQuery:@"SELECT COUNT(*) FROM myTable"];   
if ([s next]) {    
    int totalCount = [s intForColumnIndex:0];   
}

 

FMResultSet 提供了很多方法來獲得所需的格式的值:

複製代碼
intForColumn:
longForColumn:
longLongIntForColumn:
boolForColumn:
doubleForColumn:
stringForColumn:
dataForColumn:
dataNoCopyForColumn:
UTF8StringForColumnIndex:
objectForColumn:
複製代碼

 

這些方法也都包括 {type}ForColumnIndex 的這樣子的方法,參數是查詢結果集的列的索引位置。
你無需調用 [FMResultSet close]來關閉結果集, 當新的結果集產生,或者其數據庫關閉時,會自動關閉。

關閉數據庫

當使用完數據庫,你應該 -close 來關閉數據庫連接來釋放SQLite使用的資源。
[db close];

使用FMDatabaseQueue 及線程安全

在多個線程中同時使用一個FMDatabase實例是不明智的。現在你可以爲每個線程創建一個FMDatabase對象。 不要讓多個線程分享同一個實例,它無法在多個線程中同時使用。 若此,壞事會經常發生,程序會時不時崩潰,或者報告異常,或者隕石會從天空中掉下來砸到你Mac Pro. 總之很崩潰。所以,不要初始化FMDatabase對象,然後在多個線程中使用。請使用 FMDatabaseQueue,它是你的朋友而且會幫助你。以下是使用方法:
首先創建隊列

FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];

這樣使用

複製代碼
[queue inDatabase:^(FMDatabase *db) {    
      [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];    
      [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];    
      [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];    
      FMResultSet *rs = [db executeQuery:@"select * from foo"];    
      while([rs next]) {   
         …    
      }    
}];
複製代碼

 

像這樣,輕鬆地把簡單任務包裝到事務裏

複製代碼
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {    
        [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];    
        [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];    
        [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];    
        if (whoopsSomethingWrongHappened) {    
                *rollback = YES; return;    
        }   
        // etc…    
        [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]];    
}];
複製代碼

 

FMDatabaseQueue將運行在一個序列化隊列塊。所以如果你從多個線程在同一時間調用FMDatabaseQueue的方法,他們將執行他們收到的指令。這樣查詢和更新不會相互影響,每一個都是快樂的。

發佈了84 篇原創文章 · 獲贊 107 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章