iOS學習47之第三方-FMDB,ios47-fmdb

來源:互聯網
上載者:User

iOS學習47之第三方-FMDB,ios47-fmdb

將 CocoaPods 安裝後,按照 CocoaPods 的使用說明就可以將 FMDB 第三方整合到工程中,具體請看部落格iOS學習46之第三方CocoaPods的安裝和使用(通用方法)

1. FMDB簡介 1> 概述
  • iOS 中原生的 SQLite API 在進行資料存放區的時候,需要使用 C語言 中的函數,操作比較繁瑣。於是,就出現了一系列將SQLite API 進行封裝的庫,例如 FMDB、PlausibleDatabase、SQLitePersistentObjects 等。  

  • FMDB 是一款簡潔、易用的封裝庫。因此,在這裡推薦使用第三方架構 FMDB,它是對 libsqlite3 架構的封裝,用起來的步驟與 SQLite 使用類似,並且它對於多線程的並行作業進行了處理,所以是安全執行緒的。

 2> FMDB優缺點
  • 優點:

  對多線程的並行作業進行處理,所以是安全執行緒的;

  以OC的方式封裝了SQLite的C語言API,使用起來更加的方便;

  FMDB是輕量級的架構,使用靈活。

  • 缺點:

  因為它是OC的語言封裝的,只能在iOS開發的時候使用,所以在實現跨平台操作的時候存在局限性。

 3> FMDB中重要的類

  • FMDatabase:一個 FMDatabase 對象就代表一個單獨的 SQLite資料庫,用來執行 SQL語句。

  • FMResultSet:使用 FMDatabase 執行查詢後的結果集。

  • FMDatabaseQueue:用於在多線程中執行多個查詢或更新,它是安全執行緒的。

 4> FMDB使用步驟

  • 第一步:使用 CocoaPods 將第三方整合到工程項目中

  • 第二步:匯入 libsqlite3.0 架構,匯入標頭檔 FMDatabase.h

  • 第三步:代碼實現,與 SQLite 使用步驟相似,建立資料庫路徑,獲得資料庫路徑,開啟資料庫,然後對資料庫進行增、刪、改、查操作,最後關閉資料庫。

2. FMDB建立資料庫和資料表
  • 第一步:獲得資料庫檔案的路徑

  建立FMDatabase對象時參數為SQLite資料庫檔案路徑,該路徑可以是以下三種方式之一:

   ① 檔案路徑。該檔案路徑無需真實存在,如果不存在會自動建立;

   ② Null 字元串(@"")。表示會在臨時目錄建立一個空的資料庫,當 FMDatabase 串連關閉時,檔案也會被刪除;

   ③ NULL。將建立一個內在資料庫,同樣的,當 FMDatabase 串連關閉時,資料將會被銷毀。

  我們一般採用第一種方式來獲得資料庫檔案的路徑,具體執行個體代碼如下:

   NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];    self.filePath = [documentPath stringByAppendingPathComponent:@"student.sqlite"];    NSLog(@"filePath = %@", self.filePath);
  • 第二步:使用路徑初始化FMDB對象

  使用的初始化方法:

   + (instancetype)databaseWithPath:(NSString*)aPath

  執行個體代碼:

    // 第四步:使用路徑初始化FMDB對象    self.database = [FMDatabase databaseWithPath:self.filePath];
  • 第三步:在和資料庫互動之前,資料庫必須是開啟的。

  如果許可權不足或者資源不足,則無法開啟和建立資料庫。

   // 需要判斷資料庫開啟的時候才進行執行語句   if (self.database.open) {        // 建立表    }
  • 第四步:建立表

  使用的執行SQL語句的方法:

    - (BOOL)executeUpdate:(NSString*)sql, ...

  該方法的傳回值是一個BOOL值,我們可以根據傳回值,來判斷SQL語句是否執行成功。

  執行個體代碼:

    if (self.database.open) {        // 建表語句        NSString *createSql = @"create table if not exists t_student(id integer primary key autoincrement not null, name text not null, age integer not null, sax text not null)";        // 執行建表語句,建立資料表        BOOL result = [self.database executeUpdate:createSql];        // 判斷是否建表成功        if (result) {            NSLog(@"創表成功");        } else {            NSLog(@"創表失敗");        }    }
  • 第五步:關閉資料庫

  執行個體代碼:

    // 第五步:關閉資料庫    [self.database close];
3. FMDB實現增、刪、改、查 1> FMDB—執行更新

  一切不是SELECT命令的命令都視為更新。這包括CREAT,UPDATE,INSERT,ALTER,BEGIN,COMMIT,DETACH,DELETE,DROP,END,EXPLAIN,VACUUM,REPLACE等。  

  簡單來說,只要不是以 SELECT 開頭的命令都是更新命令。

      執行更新返回一個BOOL值。YES表示執行成功,否則表示有錯誤。你可以調用 -lastErrorMessage 和 -lastErrorCode方法來得到更多資訊。

 2> 執行更新命令的相關方法
  • executeUpdate:  不確定的參數用 ? 來佔位(後面參數必須是 OC 對象,;代表語句結束,也可以不寫)

  增、刪、改的代碼執行個體:

// 增加(插入)資料BOOL result = [self.database executeUpdate:@"insert into t_student(name, age, sax) values(?, ?, ?)", @"xiaoming", @12, @"男"];// 更新資料BOOL result = [self.database executeUpdate:@"update t_student set name = ? where name = ?", @"xiaoming", @"小明"];// 刪除資料BOOL result = [self.database executeUpdate:@"delete from t_student where name = ?", @"xiaoming"]; 
  • executeUpdateWithFormat:不確定的參數用%@,%d等來佔位 (參數為未經處理資料類型,執行語句不區分大小寫)

  增、刪、改的代碼執行個體:

// 增加(插入)資料BOOL result = [self.database executeUpdateWithFormat:@"insert into t_student (name, age, sax) values (%@, %i, %@);", @"xiaoming", @69, @"男"];// 更新資料BOOL result = [self.database executeUpdateWithFormat:@"update t_student set name = %@ where name = %@", @"xiaoming", @"小明"];// 刪除資料BOOL result = [self.database executeUpdateWithFormat:@"delete from t_student where name = %@", @"xiaoming"];
  • executeUpdate:withArgumentsInArray:數組,直接使用數組

  增、刪、改的代碼執行個體:

// 增加(插入)資料[self.database executeUpdate:@"insert into t_student(name, age, sax) values(?, ?, ?);"  withArgumentsInArray:@[@"xiaoming", @12, @"男"]];// 更新資料[self.database executeUpdate:@"update t_student set name = ? where name = ?;"  withArgumentsInArray:@[@"xiaoming", @"小明"]];// 刪除資料[self.database executeUpdate:@"delete from t_student where name = ?;"  withArgumentsInArray:@[@"xiaoming"]];

  以上的方法大家可以根據自己的習慣和需求選擇一種即可。

 3> FMDB—查詢資料  ① 概述  

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

  執行查詢時,如果成功返回 FMResultSet 對象,錯誤返回 nil 。與執行更新相同,支援使用 NSError 參數。

  同時,你也可以使用 -lastErrorCode 和 -lastErrorMessage 獲知錯誤資訊。

  ② FMResultSet

  FMResultSet 提供了很多方法,來擷取對應欄位的資訊:  

    intForColumn:、longForColumn:、longLongIntForColumn:、boolForColumn:、doubleForColumn:、stringForColumn:、dataForColumn:、dataNoCopyForColumn:、UTF8StringForColumnIndex:、objectForColumn:

  ③ 執行查詢語句

  查詢整個表

    // 查詢結果使用的類FMResultSet    FMResultSet *resultSet = [self.database executeQuery:@"select * from t_student"];

  根據條件查詢

    //根據條件查詢    FMResultSet *resultSet = [self.db executeQuery:@"select * from t_student where id<?;", @14];

  ④ 遍曆結果集合

    while (resultSet.next) {        NSInteger ID = [resultSet intForColumn:@"id"];        NSString *name = [resultSet objectForColumnName:@"name"];        NSInteger age = [resultSet intForColumn:@"age"];        NSString *sax = [resultSet objectForColumnName:@"sax"];                NSLog(@"id = %ld name = %@, age = %ld, sax = %@", ID, name, age, sax);    }
 4> 完整執行個體代碼
#import "ViewController.h"// 第一步:引入架構,引入支援的類庫(libsqlite3.0.tbd)#import <FMDB.h>@interface ViewController ()/// 聲明資料庫物件@property (nonatomic, strong) FMDatabase *database;/// 聲明儲存路徑@property (nonatomic, strong) NSString *filePath;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.    [self createTabe];}#pragma mark - 建立表- (void)createTabe{    // 第一步:建立sql語句    NSString *createSql = @"create table if not exists t_student(id integer primary key autoincrement not null, name text not null, age integer not null, sax text not null)";        // 第二步:找到儲存路徑    NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];//    NSLog(@"document = %@", documentPath);    self.filePath = [documentPath stringByAppendingPathComponent:@"student.sqlite"];    NSLog(@"filePath = %@", self.filePath);        // 第三步:使用路徑初始化FMDB對象    self.database = [FMDatabase databaseWithPath:self.filePath];        // 第四步:資料庫執行相關的操作    // 需要判斷資料庫開啟的時候才進行執行語句    if (self.database.open) {        BOOL result = [self.database executeUpdate:createSql];        if (result) {            NSLog(@"創表成功");        } else {            NSLog(@"創表失敗");        }    }        // 第五步:關閉資料庫    [self.database close];}#pragma mark - 插入- (IBAction)insertIntoAction:(id)sender{    // 第一步:開啟資料庫    [self.database open];        // 第二步:進行相關的操作    NSArray *nameArray = @[@"MBBoy", @"BoomSky", @"小明"];        for (NSString *name in nameArray) {        BOOL result = [self.database executeUpdate:@"insert into t_student(name, age, sax) values(?, ?, ?)", name, @69, @"男"]; // integer的資料不能在這裡使用,必須使用一個對象型資料,比如NSNumber、NSString...                [self.database executeUpdate:@"INSERT INTO t_student(name, age, sax) VALUES  (?, ?, ?);"  withArgumentsInArray:@[@"xiaoming", @12, @"男"]];                if (result) {            NSLog(@"插入成功");        } else {            NSLog(@"插入失敗");        }    }    [self.database close];// 更新資料// 刪除資料// 增加(插入)資料}#pragma mark - 更新- (IBAction)updateAction:(id)sender{    [self.database open];        BOOL result = [self.database executeUpdate:@"update t_student set name = ? where name = ?", @"xiaoming", @"小明"];        if (result) {        NSLog(@"更新成功");    } else {        NSLog(@"更新失敗");    }        [self.database close];}#pragma mark - 刪除- (IBAction)deleteAction:(id)sender{    [self.database open];    BOOL result = [self.database executeUpdate:@"delete from t_student where name = ?", @"MBBoy"];    if (result) {        NSLog(@"刪除成功");    } else {        NSLog(@"刪除失敗");    }    [self.database close];}#pragma mark - 查詢- (IBAction)selectAction:(id)sender{    [self.database open];        // 查詢結果使用的類FMResultSet    FMResultSet *resultSet = [self.database executeQuery:@"select * from t_student"];        // 遍曆出需要的結果內容    while (resultSet.next) {        NSInteger ID = [resultSet intForColumn:@"id"];        NSString *name = [resultSet objectForColumnName:@"name"];        NSInteger age = [resultSet intForColumn:@"age"];        NSString *sax = [resultSet objectForColumnName:@"sax"];                NSLog(@"id = %ld name = %@, age = %ld, sax = %@", ID, name, age, sax);    }        [self.database close];}@end
4. FMDB實現多線程操作 1> 概述
  • 如果應用中使用了多線程操作資料庫,那麼就需要使用 FMDatabaseQueue 來保證安全執行緒了。 應用中不可在多個線程中共同使用一個 FMDatabase 對象操作資料庫,這樣會引起資料庫資料混亂(例如使用兩個線程同時對資料庫進行更新和尋找)。

  • 多個線程更新相同的資源導致資料競爭時使用等待隊列(等待現在執行的處理結束)。

  • 以隊列的形式添加是 FMDB 比較常用的添加方式。

  • FMDB 不支援多個線程同時操作,一般使用串列方式實現相關的操作。

 2> 建立操作隊列

  使用的初始化方法

+ (instancetype)databaseQueueWithPath:(NSString*)aPath
 3> 把操作打包放在操作隊列中

  打包的方法

- (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block

  在 Block 中添加串列隊列

 4> 執行個體代碼
#pragma mark - 以隊列的形式添加很多學生- (IBAction)insertManyStudent:(id)sender{    // 以隊列的形式新增學生是FMDB比較常用的添加方式    // FMDB不支援多個線程同時操作,一般使用串列方式實現相關的操作        [self.database open];        // 第一步:建立操作隊列    FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:self.filePath];        // 標識:記錄是否操作成功    __block BOOL isSucceed = YES;        // 第二步:把操作打包放在操作隊列中    NSString *insertSql = @"insert into t_studen(name, age, sax) values(?, ?, ?)";        [queue inTransaction:^(FMDatabase *db, BOOL *rollback) {        // 串列隊列        isSucceed &= [db executeUpdate:insertSql, @"隔壁老王", @38, @"男"];        isSucceed &= [db executeUpdate:insertSql, @"Black", @18, @"女"];        isSucceed &= [db executeUpdate:insertSql, @"-1", @23, @"男"];                if (!isSucceed) {                        // block 返回的參數rollback進行處理(BOOL類型的指標)            *rollback = YES;            return;        } else {            NSLog(@"以隊列的形式添加成功");        }    }];        [self.database close];}

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.