Sqlite封裝1-基本封裝-SqliteTool

weixin_34391445發表於2017-08-02

用sqlite封裝一個資料庫

894719-1a10c7803fdbba75.png
總共需要做的一些步驟

LFSqliteTool基本封裝需要做的是:

公 / 私 API操作 返回
私有 1.開啟資料庫
私有 2.關閉資料庫
暴露 3.執行語句(增刪改) 返回是否成功
暴露 4.查詢語句(查) 返回結果集

匯入標頭檔案 #import "sqlite3.h"

一、私有方法開啟資料庫關閉資料庫供內部呼叫

sqlite3 *ppDb = nil;

1.開啟資料庫

根據使用者名稱,拼接上路徑,來開啟資料庫。

在開啟資料庫的時候,ppDb就被賦值了,便於被後面使用。

+ (BOOL)openDB:(NSString *)uid {
    NSString *dbName = @"common.sqlite";
    if (uid.length != 0) {
        dbName = [NSString stringWithFormat:@"%@.sqlite", uid];
    }
    
    NSString *dbPath = [kCachePath stringByAppendingPathComponent:dbName];
    
    // 1. 建立&開啟一個資料庫
    
    return  sqlite3_open(dbPath.UTF8String, &ppDb) == SQLITE_OK;
}

894719-5e5c02b054d90f8f.png
開啟sqlite資料庫
2.關閉資料庫
+ (void)closeDB {
    sqlite3_close(ppDb);
}
3.執行sql語句(增刪改)

傳入sql語句和使用者名稱。

+ (BOOL)deal:(NSString *)sql uid:(NSString *)uid {
    
    
    // 開啟資料庫
    if (![self openDB:uid]) {
        NSLog(@"開啟失敗");
        return NO;
    }
    
    // 2. 執行語句
    BOOL result = sqlite3_exec(ppDb, sql.UTF8String, nil, nil, nil) == SQLITE_OK;
    
    // 3. 關閉資料庫
    [self closeDB];
    
    return result;
    
}

4.查詢(難點)

步驟:

  1. 開啟資料庫

  2. 建立準備語句

    • 使用sqlite3_prepare_v2()函式來建立準備語句,而準備語句放在該函式的第四個引數ppStmt中,型別為sqlite3_stmt
    • sqlite3_stmt型別:將一個SQL命令字串轉換成一條prepared語句,儲存在sqlite3_stmt型別結構體中。(即sqlite3_stmt起一個轉換作用,把字串轉換成sqlite能用的。)
    • 每次執行sqlite函式,都要用到ppStmt。
  3. 繫結資料(本次可以省略)

  4. 執行查詢
    遍歷每一行,以下對每一行記錄操作:

    • 獲取所有列的個數
    • 遍歷所有的列
      • 獲取列名
      • 獲取列值
        • 獲取列的型別
        • 根據列的型別, 使用不同的函式, 進行獲取
  5. 重置(省略)

  6. 釋放資源

  7. 返回一個可變字典(欄位 - value)

這裡忽略了繫結和重置兩個步驟。

+ (NSMutableArray <NSMutableDictionary *>*)querySql:(NSString *)sql uid:(NSString *)uid {
    [self openDB:uid];
    // 準備語句(預處理語句)
    
    // 1. 建立準備語句
    // 引數1: 一個已經開啟的資料庫
    // 引數2: 需要中的sql
    // 引數3: 引數2取出多少位元組的長度 -1 自動計算 \0
    // 引數4: 準備語句
    // 引數5: 通過引數3, 取出引數2的長度位元組之後, 剩下的字串
    sqlite3_stmt *ppStmt = nil;
    if (sqlite3_prepare_v2(ppDb, sql.UTF8String, -1, &ppStmt, nil) != SQLITE_OK) {
        NSLog(@"準備語句編譯失敗");
        return nil;
    }
    
    // 2. 繫結資料(省略)
    
    // 3. 執行
    // 大陣列
    NSMutableArray *rowDicArray = [NSMutableArray array];
    while (sqlite3_step(ppStmt) == SQLITE_ROW) {
        // 一行記錄 -> 字典
        // 1. 獲取所有列的個數
        int columnCount = sqlite3_column_count(ppStmt);
        
        NSMutableDictionary *rowDic = [NSMutableDictionary dictionary];
        [rowDicArray addObject:rowDic];
        // 2. 遍歷所有的列
        for (int i = 0; i < columnCount; i++) {
            // 2.1 獲取列名
            const char *columnNameC = sqlite3_column_name(ppStmt, i);
            NSString *columnName = [NSString stringWithUTF8String:columnNameC];
            
            // 2.2 獲取列值
            // 不同列的型別, 使用不同的函式, 進行獲取
            // 2.2.1 獲取列的型別
            int type = sqlite3_column_type(ppStmt, i);
            // 2.2.2 根據列的型別, 使用不同的函式, 進行獲取
            id value = nil;
            switch (type) {
                case SQLITE_INTEGER:
                    value = @(sqlite3_column_int(ppStmt, i));
                    break;
                case SQLITE_FLOAT:
                    value = @(sqlite3_column_double(ppStmt, i));
                    break;
                case SQLITE_BLOB:
                    value = CFBridgingRelease(sqlite3_column_blob(ppStmt, i));
                    break;
                case SQLITE_NULL:
                    value = @"";
                    break;
                case SQLITE3_TEXT:
                    value = [NSString stringWithUTF8String: (const char *)sqlite3_column_text(ppStmt, i)];
                    break;
                    
                default:
                    break;
            }
            
            [rowDic setValue:value forKey:columnName];
 
        }
    }
    
    
    // 4. 重置(省略)
    
    // 5. 釋放資源
    sqlite3_finalize(ppStmt);
    
    [self closeDB];
    
    return rowDicArray;
}


894719-0cce963d4479cb5c.png
Snip20170802_97.png

相關文章