FMDB在項(xiàng)目中的封裝使用

FMDB

框架下載地址:https://github.com/ccgus/fmdb
速度比CoreData快幾十倍,realm我一直沒有用,不做過多評價(jià),現(xiàn)在聊一聊我在項(xiàng)目中是如何使用FMDB的

單例封裝###

創(chuàng)建一個(gè)WYSQLiteManager繼承自NSObject,里面主要用到的是FMDB中的FMDatabaseQueue

#import <Foundation/Foundation.h>
#import "FMDB.h"
@class FMDatabaseQueue;

@interface WYSQLiteManager : NSObject

@property (nonatomic, strong) FMDatabaseQueue *queue;

+ (instancetype)sharedManager;

@end

.m中的代碼:

#import "WYSQLiteManager.h"
// 數(shù)據(jù)庫名稱
NSString *const dbName = @"nightChat.db";

@implementation WYSQLiteManager

+ (instancetype)sharedManager {
    static id _instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[WYSQLiteManager alloc] init];
    });
    return _instance;
}

- (instancetype)init {
    if (self = [super init]) {
      // 數(shù)據(jù)庫在沙盒中的路徑
        NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
        path = [path stringByAppendingPathComponent:dbName];
        // 使用數(shù)據(jù)庫路徑初始化FMDatabaseQueue
        self.queue = [[FMDatabaseQueue alloc] initWithPath:path];
        [self createTables];
    }
    return self;
}

- (void)createTables {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"tables.sql" ofType:nil];
    NSError *error = nil;
    // 加載所有的建表語句
    NSString *sql = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
    if (error) {
        NSLog(@"加載數(shù)據(jù)庫建表語句錯(cuò)誤--%@", error);
    }
    
    // 創(chuàng)建表
    [self.queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
        [db executeStatements:sql];
    }];
}

我的tables.sql[這里只給出了一個(gè)建表語句]

-- fateMessage 有緣人消息列表
CREATE TABLE IF NOT EXISTS "T_Fate_Message" (
"messageId" INTEGER NOT NULL,   -- 消息ID
"content" TEXT,                 -- 消息內(nèi)容
"owner_id" INTEGER,             -- 消息擁有者ID
"sender_id" INTEGER,            -- 消息發(fā)送者ID
"receiver_id" INTEGER,          -- 消息接受者ID
"timestamp" LONG,               -- 消息發(fā)送時(shí)間
"deliveryState" INTEGER,        -- 消息發(fā)送狀態(tài)
"mfrom" TEXT,                   -- 消息來源的環(huán)信用戶名
"mto" TEXT,                     -- 消息接受者的環(huán)信用戶名
"extern" TEXT,                  -- 預(yù)留字段
"ID" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT
);

啰嗦兩句,一般創(chuàng)建表的時(shí)候都會(huì)有一兩個(gè)預(yù)留字段,因?yàn)槿绻褂昧藄qlite過后,項(xiàng)目發(fā)版上線了,后面要對數(shù)據(jù)庫表做變動(dòng)[例如增加字段],這個(gè)時(shí)候是需要做數(shù)據(jù)遷移的,這個(gè)會(huì)比較麻煩,所以一般的辦法都是在建表的時(shí)候就多創(chuàng)建兩個(gè)預(yù)留字段.并且在大多數(shù)時(shí)候存儲(chǔ)的都是json字符串,這樣的變動(dòng)性會(huì)比較好,一般單獨(dú)的字段大多是需要用作查詢處理的.

數(shù)據(jù)庫操作##

一般我們還會(huì)單獨(dú)針對不同模塊的本地化數(shù)據(jù)操作創(chuàng)建不同的數(shù)據(jù)訪問層,例如這里創(chuàng)建一個(gè)WYFateMessageDAL

/// 有緣人消息保存
///
/// @param message 要保存的消息
+ (BOOL)fateMessageSave:(EMMessage *)message {
    NSString *sql = @"insert or replace into T_Fate_Message (messageId, content, owner_id, timestamp, deliveryState, mfrom, mto) values (?, ?, ?, ?, ?, ?, ?);";
    
    return [self insertFateMessage:message sql:sql];
}

/// 保存有緣人消息
///
/// @param message 有緣人消息
/// @param sql     sql語句
///
/// @return 插入結(jié)果
+ (BOOL)insertFateMessage:(EMMessage *)message sql:(NSString *)sql {
    __block BOOL success = false;
    [[WYSQLiteManager sharedManager].queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
        success = [db executeUpdate:sql, message.messageId, message.contentText, GetUserID, @(message.timestamp), @(message.deliveryState), message.from, message.to];
        [self stateLog:success rollback:rollback];
    }];
    return success;
}

注意點(diǎn)###

FMDatabaseQueue是一個(gè)串行隊(duì)列,目的就是為了保證數(shù)據(jù)的安全性,所以我們在做數(shù)據(jù)操作的時(shí)候一定要注意多線程并發(fā)訪問的數(shù)據(jù)造成的數(shù)據(jù)錯(cuò)亂,所以在使用的時(shí)候記住在主線程做數(shù)據(jù)庫訪問操作.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容