使用iOS原生sqlite3框架對sqlite數據庫進行操做

使用iOS原生sqlite3框架對sqlite數據庫進行操做

1、引言

      sqlite數據庫是一種小型數據庫,因爲其小巧與簡潔,在移動開發領域應用深廣,sqlite數據庫有一套完備的sqlite語句進行管理操做,一些經常使用的語句和可視化的開發工具在上篇博客中有介紹,地址以下:git

sqlite數據庫經常使用語句及可視化工具介紹:http://my.oschina.net/u/2340880/blog/600820github

      在iOS的原生開發框架中能夠對sqlite數據庫進行很好的支持,這個框架中採用C風格且經過指針移動進行數據的操做,使用起來有些不便,咱們能夠對一些數據庫的經常使用操做進行一些面向對象的封裝。sql

2、libsqlite3系統庫中操做數據庫的經常使用方法

    libsqlite3是對sqlite數據庫進行操做的系統庫,在使用前,咱們須要先導入,點擊Xcode的Build Phases標籤,展開Link Binary With Libraries,點擊+號,在彈出的窗口中搜索libsqlite3.0,將其導入進工程,過程以下圖:數據庫

 

在須要操做sqlite數據的文件中導入以下頭文件:設計模式

#import <sqlite3.h>

 

數據庫文件的操做是由一個sqlite3類型的指針操做管理的,以下方法進行數據庫的打開:app

sqlite3 *sqlite;
sqlite3_open(dataBaePath, &sqlite)

 

sqlite3_open方法返回一個int值,實際上,在使用libsqlite3框架中的大多方法時都會返回一個int值,這個int值表明着方法執行的相應結果狀態,這些狀態再sqlite3.h文件中經過宏來定義,列舉以下:框架

#define SQLITE_OK           0   //操做成功
/* 如下是錯誤代碼 */
#define SQLITE_ERROR        1   /* SQL數據庫錯誤或者丟失*/
#define SQLITE_INTERNAL     2   /* SQL內部邏輯錯誤 */
#define SQLITE_PERM         3   /* 沒有訪問權限 */
#define SQLITE_ABORT        4   /* 回調請求終止 */
#define SQLITE_BUSY         5   /* 數據庫文件被鎖定 */
#define SQLITE_LOCKED       6   /* 數據庫中有表被鎖定 */
#define SQLITE_NOMEM        7   /* 分配空間失敗 */
#define SQLITE_READONLY     8   /* 企圖向只讀屬性的數據庫中作寫操做 */
#define SQLITE_INTERRUPT    9   /* 經過sqlite3_interrupt()方法終止操做*/
#define SQLITE_IOERR       10   /* 磁盤發生錯誤 */
#define SQLITE_CORRUPT     11   /* 數據庫磁盤格式不正確 */
#define SQLITE_NOTFOUND    12   /* 調用位置操做碼 */
#define SQLITE_FULL        13   /* 因爲數據庫已滿形成的添加數據失敗 */
#define SQLITE_CANTOPEN    14   /* 不法打開數據庫文件 */
#define SQLITE_PROTOCOL    15   /* 數據庫鎖協議錯誤 */
#define SQLITE_EMPTY       16   /* 數據庫爲空 */
#define SQLITE_SCHEMA      17   /* 數據庫模式更改 */
#define SQLITE_TOOBIG      18   /* 字符或者二進制數據超出長度 */
#define SQLITE_CONSTRAINT  19   /* 違反協議終止 */
#define SQLITE_MISMATCH    20   /* 數據類型不匹配 */
#define SQLITE_MISUSE      21   /* 庫使用不當 */
#define SQLITE_NOLFS       22   /* 使用不支持的操做系統 */
#define SQLITE_AUTH        23   /* 受權拒絕 */
#define SQLITE_FORMAT      24   /* 輔助數據庫格式錯誤 */
#define SQLITE_RANGE       25   /* sqlite3_bind 第二個參數超出範圍 */
#define SQLITE_NOTADB      26   /* 打開不是數據庫的文件 */
#define SQLITE_NOTICE      27   /* 來自sqlite3_log()的通知 */
#define SQLITE_WARNING     28   /* 來自sqlite3_log() 的警告*/
#define SQLITE_ROW         100  /* sqlite3_step() 方法準備好了一行數據 */
#define SQLITE_DONE        101  /* sqlite3_step() 已完成執行*/

 

執行非查詢類的語句,例如建立,添加,刪除等操做,使用以下方法:工具

char * err;
sqlite3 *sql;
sqlite3_exec(sql, sqlStr, NULL, NULL, &err);

 

sqlite3_exec方法中第一個參數爲成功執行了打開數據庫操做的sqlite3指針,第二個參數爲要執行的sql語句,最後一個參數爲錯誤信息字符串。開發工具

執行查詢語句的方法比較複雜,經過以下方法:ui

    sqlite3 * sqlite;
    sqlite3_stmt *stmt =nil;
    int code = sqlite3_prepare_v2(sqlite, sqlStr, -1, &stmt, NULL);
     while (sqlite3_step(stmt)==SQLITE_ROW) {
         char * cString =(char*)sqlite3_column_text(stmt, 0);
         NSString * value = [NSString stringWithCString:cString?cString:"NULL" encoding:NSUTF8StringEncoding];
         NSNumber * value = [NSNumber numberWithLongLong:sqlite3_column_int64(stmt, 1)];
        }
         sqlite3_finalize(stmt);

 

stmt是一個數據位置指針,標記查詢到數庫的數據位置,sqlite3_prepare_v2()方法進行數據庫查詢的準備工做,第一個參數爲成功打開的數據庫指針,第二個參數爲要執行的查詢語句,第三個參數爲sqlite3_stmt指針的地址,這個方法也會返回一個int值,做爲標記狀態是否成功。

sqlite3_step方法對stmt指針進行移動,會逐行進行移動,這個方法會返回一個int值,若是和SQLITE_ROW宏對應,則代表有此行數據,能夠經過while循環來對數據進行讀取。

sqlite3_column_XXX()是取行中每一列的數據,根據數據類型的不一樣,sqlite3_column_XXX()有一系列對應的方法,這個方法中第一個參數是stmt指針,第二個參數爲列序號。

sqlite3_finalize()方法對stmt指針進行關閉。

3、面向對象的sqlite數據庫操做框架封裝

        網上不乏有許多優秀的第三方sqlite數據庫使用框架,FFDM就是其中之一,而且apple自帶的coreData也十分優秀。這篇博客中所述內容並不全面,代碼也並不十分完善健壯,封裝出來的代碼除了可以完成基本的數據庫操做外,更多主要是對設計思路的示例。

1.面向對象的sqlite管理類的設計思路

        爲了便於使用,在設計時,咱們儘可能將libsqlite3中的方法不暴漏在使用層,經過面向應用的接口來進行方法的設計,設計思路類圖以下:

圖中,文件管理中心對文件進行存取刪改管理,不暴漏在外,數據庫管理中心負責對數據庫的建立,刪除打開等操做,具體的數據操做由數據庫操做對象來完成。

2.文件管理中心方法的編寫

        文件管理中心主要負責對數據庫文件的存取,能夠實現以下方法:

YHBaseCecheCenter.h

/**
 *  @brief 獲取數據庫方法的地址
 *
 *  @return 地址字符串
 *
 */
-(NSString *)getDataBaseFilePath;
/**
 *  @brief 獲取某個數據庫的大小
 *
 *  @param name 數據庫名稱
 *
 *  @return 文件大小 單位M
 *
 */
-(float)getSizeFromDataBaseName:(NSString *)name;

 

YHBaseCecheCenter.m

-(NSString *)getDataBaseFilePath{
    return NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
}
-(float)getSizeFromDataBaseName:(NSString *)name{
    NSString * path = [NSString stringWithFormat:@"/%@/%@",NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject,name];
    return  [self fileSizeAtPath:path]/(1024.0*1024.0);
}
//獲取文件大小
- (long long) fileSizeAtPath:(NSString*) filePath{
    NSFileManager* manager = [NSFileManager defaultManager];
    if ([manager fileExistsAtPath:filePath]){
        return [[manager attributesOfItemAtPath:filePath error:nil] fileSize];
    }
    return 0;
}

 

在iOS系統中由於其沙盒結構的限制,數據庫必須方法documents目錄下才能正常打開使用。

3.數據庫管理中心的設計

        數據庫管理中心主要負責對數據庫的宏觀操做,採用類方法的設計模式,以下

YHBaseSQLiteManager.h

/**
 *  @brief 打開一個數據庫 若是不存在則會建立
 *
 *  @param name 數據庫名稱
 *
 *  @return 數據庫操做對象 若是建立失敗會返回nil
 *
 */
+(YHBaseSQLiteContext *)openSQLiteWithName:(NSString *)name;
/**
 *  @brief 獲取數據庫文件的大小 單位M
 *
 *  @param dataBase 數據庫上下文對象
 *
 *  @return 數據庫文件大小
 */
+(float)getSizeOfDataBase:(YHBaseSQLiteContext *)dataBase;
/**
 *  @brief 獲取數據庫文件的大小 單位M
 *
 *  @param dataBaseName 數據庫名稱
 *
 *  @return 數據庫文件大小
 */
+(float)getSizeOfDataBaseName:(NSString *)dataBaseName;
/**
 *  @brief 刪除全部數據庫
 *
 */
+(void)removeDataBase;

 

 YHBaseSQLiteManager.m

+(YHBaseSQLiteContext *)openSQLiteWithName:(NSString *)name{
    
    NSString * path =  [[YHBaseCecheCenter sharedTheSingletion]getDataBaseFilePath];
    YHBaseSQLiteContext * context = [[YHBaseSQLiteContext alloc]init];
    context.name = name;
    BOOL success = [context openDataBaeWithName:[NSString stringWithFormat:@"%@/%@",path,name]];
    if (success) {
        return context;
    }else{
        return nil;
    }
}
+(float)getSizeOfDataBase:(YHBaseSQLiteContext *)dataBase{
    return [[YHBaseCecheCenter sharedTheSingletion]getSizeFromDataBaseName:dataBase.name];
}
+(float)getSizeOfDataBaseName:(NSString *)dataBaseName{
    return [[YHBaseCecheCenter sharedTheSingletion]getSizeFromDataBaseName:dataBaseName];
}
+(void)removeDataBase{
    NSString * path =  [[YHBaseCecheCenter sharedTheSingletion]getDataBaseFilePath];
    return [[YHBaseCecheCenter sharedTheSingletion]removeCacheFromPath:path];
}

 

4.數據庫操做對象

        將操做數據庫的核心方法封裝在這個類中:

YHBaseSQLiteContext.h

/**
 *操做的數據庫名稱
 */
@property(nonatomic,strong)NSString * name;
/**
 *內含sqlite3 對象
 */
@property(nonatomic,assign)sqlite3 * sqlite3_db;
/**
 * @brief 打開一個數據庫 不存在則建立
 *
 * @param path 數據庫路徑
 *
 * @return 是否操做成功
 */
-(BOOL)openDataBaeWithName:(NSString *)path;
/**
 *  @brief 再數據庫中建立一張表 若是已經存在 會返回錯誤信息
 *
 *  @param name 表的名稱
 *
 *  @prarm dic 表中的鍵 其中字典中需傳入 鍵名:類型  類型的宏定義在YHBaseSQLTypeHeader.h中
 *
 *  @param callBack 結果回調
 */
-(void)createTableWithName:(NSString *)name
            keysDictionary:(NSDictionary<NSString*,NSString*> *) dic
                  callBack:(void (^)(YHBaseSQLError * error))complete;

/**
 *  @brief 向表中添加一條數據
 *
 *  @param dataDic 添加數據的鍵值對
 *
 *  @param name 插入表的名稱
 *
 *  @complete 回調
 */
-(void)insertData:(NSDictionary<NSString *,id>*)dataDic
        intoTable:(NSString *)name
         callBack:(void (^)(YHBaseSQLError * error))complete;
/**
 *  @brief 向表中添加一個鍵
 *
 *  @param kName 添加的鍵
 *
 *  @prarm type 類型
 *
 *  @prarm tableName 表名稱
 *
 *  @prarm complete 結果回調
 */
-(void)addKey:(NSString *)kName
      keyType:(NSString *)type
    intoTable:(NSString *)tableName
     callBack:(void(^)(YHBaseSQLError *error))complete;
/**
 *  @brief 修改數據
 *
 *  @param dataDic 新的鍵值
 *
 *  @param wlStr 條件字符串 通常經過主鍵找到對應數據修改 能夠爲nil
 *
 *  @param complete 結果回調
 */
-(void)update:(NSDictionary<NSString*,id> *)dataDic
      inTable:(NSString *)tableName
  whileString:(NSString *)wlStr
     callBack:(void(^)(YHBaseSQLError * error))complete;
/**
 *  @brief 刪除數據
 *
 *  @param tableName 表名
 *
 *  @param wlStr 條件字符串 通常經過主鍵找到對應數據刪除 能夠爲nil 不傳這個參數將刪除全部數據
 *
 */
-(void)deleteDataFromTable:(NSString *)tableName
               whereString:(NSString *)wlStr
                  callBack:(void(^)(YHBaseSQLError * error))complete;
/**
 *  @brief 刪除一張表
 *
 *  @param tableName 表名
 *
 */
-(void)dropTable:(NSString *)tableName
        callBack:(void(^)(YHBaseSQLError * error))complete;
/**
 *  @brief 查詢數據
 *
 *  @param keys 要查詢的鍵值 及其對應的數據類型 能夠爲nil則查詢所有
 *
 *  @param tableName 表名
 *
 *  @param orderKey 進行排序的鍵值 能夠爲nil 則不排序
 *
 *  @param type 排序方式 在YHBaseSQLTypeHeader中有宏定義
 *
 *  @param wlstr 查詢條件 同於查詢單個數據
 *
 *  @param complete dataArray爲查詢到的數據 其內爲字典
 *
 */
-(void)selectKeys:(NSArray<NSDictionary *> *)keys
        fromTable:(NSString*)tableName
          orderBy:(NSString *)orderKey
        orderType:(NSString *)type
         whileStr:(NSString *)wlstr
         callBack:(void(^)(NSArray<NSDictionary *> * dataArray,YHBaseSQLError * error))complete;
/**
 *  @brief 關閉數據庫上下文操做
 *  調用此方法後 這個context對象將再也不有效 若是再須要使用 須要YHBaseSQLiteManager中的類方法再次返回
 */
-(void)closeContext;

 

YHBaseSQLiteContext.m

-(BOOL)openDataBaeWithName:(NSString *)path{
    if (sqlite3_open([path UTF8String], &_sqlite3_db)!=SQLITE_OK) {
        sqlite3_close(_sqlite3_db);
        _sqlite3_db=nil;
        return NO;
    }else{
        return YES;
    }
}
-(void)createTableWithName:(NSString *)name keysDictionary:(NSDictionary<NSString *,NSString *> *)dic callBack:(void (^)(YHBaseSQLError *))complete{
    NSMutableString * keys = [[NSMutableString alloc]init];
    for (int i=0; i<dic.allKeys.count; i++) {
        NSString * key = dic.allKeys[i];
        if (i<dic.allKeys.count-1) {
            [keys appendFormat:@"%@ %@,",key,[dic objectForKey:key]];
        }else{
            [keys appendFormat:@"%@ %@",key,[dic objectForKey:key]];
        }
    }
    NSString * sqlStr = [NSString stringWithFormat:@"create table %@(%@)",name,keys];
    [self runSQL:sqlStr callBack:^(YHBaseSQLError * error) {
        
        if (complete) {
            complete(error);
        }
        
    }];
}
-(void)insertData:(NSDictionary<NSString *,id> *)dataDic intoTable:(NSString *)name callBack:(void (^)(YHBaseSQLError *))complete{
    NSMutableString * keys = [[NSMutableString alloc]init];
    NSMutableString * values = [[NSMutableString alloc]init];
    for (int i=0; i<dataDic.allKeys.count; i++) {
        NSString * key = dataDic.allKeys[i];
        if (i<dataDic.count-1) {
            [keys appendFormat:@"%@,",key];
            [values appendFormat:@"\"%@\",",[dataDic objectForKey:key]];
        }else{
            [keys appendFormat:@"%@",key];
            [values appendFormat:@"\"%@\"",[dataDic objectForKey:key]];
        }
    }
    NSString * sqlStr = [NSString stringWithFormat:@"insert into %@(%@) values(%@)",name,keys,values];
    [self runSQL:sqlStr callBack:^(YHBaseSQLError *error) {
        
        if (complete) {
            complete(error);
        }
        
    }];
}
-(void)addKey:(NSString *)kName keyType:(NSString *)type intoTable:(NSString *)tableName callBack:(void (^)(YHBaseSQLError *))complete{
    NSString * sqlStr = [NSString stringWithFormat:@"alter table %@ add %@ %@",tableName,kName,type];
    [self runSQL:sqlStr callBack:^(YHBaseSQLError *error) {
        if (complete) {
            complete(error);
        }
    }];
}
-(void)update:(NSDictionary<NSString *,id> *)dataDic inTable:(NSString *)tableName whileString:(NSString *)wlStr callBack:(void (^)(YHBaseSQLError *))complete{
    NSMutableString * sqlStr = [[NSMutableString alloc]init];
    [sqlStr appendFormat:@"update %@ set ",tableName];
    for (int i=0; i<dataDic.allKeys.count; i++) {
        NSString * key = dataDic.allKeys[i];
        if (i<dataDic.allKeys.count-1) {
            [sqlStr appendFormat:@"%@=\"%@\",",key,[dataDic objectForKey:key]];
        }else{
            [sqlStr appendFormat:@"%@=\"%@\"",key,[dataDic objectForKey:key]];
            if (wlStr!=nil) {
                [sqlStr appendFormat:@" where %@",wlStr];
            }
        }
    }
    [self runSQL:sqlStr callBack:^(YHBaseSQLError *error) {
        if (complete) {
            complete(error);
        }
    }];
}


-(void)deleteDataFromTable:(NSString *)tableName whereString:(NSString *)wlStr callBack:(void (^)(YHBaseSQLError *))complete{
    NSMutableString * sqlStr = [[NSMutableString alloc]init];
    [sqlStr appendFormat:@"delete from %@",tableName];
    if (wlStr!=nil) {
        [sqlStr appendFormat:@" where %@",wlStr];
    }
    [self runSQL:sqlStr callBack:^(YHBaseSQLError *error) {
        if (complete) {
            complete(error);
        }
    }];
}
-(void)dropTable:(NSString *)tableName callBack:(void (^)(YHBaseSQLError *))complete{
    NSString * sqlStr = [NSString stringWithFormat:@"drop table %@",tableName];
    [self runSQL:sqlStr callBack:^(YHBaseSQLError *error) {
        if (complete) {
            complete(error);
        }
    }];
}
-(void)selectKeys:(NSArray<NSDictionary *> *)keys fromTable:(NSString *)tableName orderBy:(NSString *)orderKey orderType:(NSString *)type whileStr:(NSString *)wlstr callBack:(void (^)(NSArray<NSDictionary *> *, YHBaseSQLError *))complete{
    NSMutableString * sqlStr = [[NSMutableString alloc]init];
    [sqlStr appendFormat:@"select"];
    if (keys==nil||keys.count==0) {
        [sqlStr appendFormat:@" * from %@",tableName];
    }else{
        for (int i=0; i<keys.count; i++) {
            if (i<keys.count-1) {
                [sqlStr appendFormat:@" %@,",keys[i].allKeys.firstObject];
            }else{
                [sqlStr appendFormat:@" %@ from %@",keys[i].allKeys.firstObject,tableName];
            }
            
        }
    }
    if (wlstr) {
        [sqlStr appendFormat:@" where %@",wlstr];
    }
    if (orderKey) {
        [sqlStr appendFormat:@" order by %@",orderKey];
    }
    if (type) {
        [sqlStr appendFormat:@" %@",type];
    }
    NSMutableArray * keysArr = [[NSMutableArray alloc]init];
    NSMutableArray * keysTypeArr = [[NSMutableArray alloc]init];
    if (keys==nil||keys.count==0) {
        NSArray<NSDictionary *> * tmpArr = [self getTheTableAllKeys:tableName];
        for (int i=0; i<tmpArr.count; i++) {
            NSString * key = tmpArr[i].allKeys.firstObject;
            [keysArr addObject:key];
            [keysTypeArr addObject:[tmpArr[i] objectForKey:key]];
        }
    }else{
        for (int i=0; i<keys.count; i++) {
            NSString * key = keys[i].allKeys.firstObject;
            [keysArr addObject:key];
            [keysTypeArr addObject:[keys[i] objectForKey:key]];
        }
    }
    
    [self runSelectSQL:sqlStr withKeys:keysArr withDataType:keysTypeArr callBack:^(NSArray<NSDictionary *> *dataArray, YHBaseSQLError *error) {
        if (complete) {
            complete(dataArray,error);
        }
    }];
   
}
-(void)closeContext{
    sqlite3_close(_sqlite3_db);
    _sqlite3_db = nil;
}

//內部方法 運行建立獨立的非查詢SQL語句
-(void)runSQL:(NSString *)sql callBack:(void(^)(YHBaseSQLError * error))complete{
    char * err;
    int code = sqlite3_exec(_sqlite3_db, [sql UTF8String], NULL, NULL, &err);
    if (code!=SQLITE_OK) {
        YHBaseSQLError * error = [[YHBaseSQLError alloc]init];
        error.errorInfo = [NSString stringWithCString:err encoding:NSUTF8StringEncoding];
        error.errorCode = code;
        complete(error);
    }else{
        complete(nil);
    }
}
//運行查詢語句
-(void)runSelectSQL:(NSString *)sql withKeys:(NSArray *)keys withDataType:(NSArray *)dataType callBack:(void(^)(NSArray<NSDictionary *> * dataArray, YHBaseSQLError * error))complete{
    sqlite3_stmt *stmt =nil;
    int code = sqlite3_prepare_v2(_sqlite3_db, [sql UTF8String], -1, &stmt, NULL);
    if (code!=SQLITE_OK) {
        YHBaseSQLError * error = [[YHBaseSQLError alloc]init];
        error.errorInfo = @"查詢失敗";
        error.errorCode=code;
        complete(nil,error);
    }else{
        NSMutableArray * resultArray = [[NSMutableArray alloc]init];
        
        while (sqlite3_step(stmt)==SQLITE_ROW) {
            //數據類型的分別解析
            NSMutableDictionary * dic = [[NSMutableDictionary alloc]init];
            for (int i=0; i<dataType.count; i++) {
                NSString * type = dataType[i];
                if ([type isEqualToString:YHBASE_SQL_DATATYPE_BINARY]) {
                    int length = sqlite3_column_bytes(stmt, i);
                    const void *data = sqlite3_column_blob(stmt, i);
                    NSData * value = [NSData dataWithBytes:data length:length];
                    [dic  setObject:value forKey:keys[i]];
                }else if([type isEqualToString:YHBASE_SQL_DATATYPE_BLOB]){
                    int length = sqlite3_column_bytes(stmt, i);
                    const void *data = sqlite3_column_blob(stmt, i);
                    NSData * value = [NSData dataWithBytes:data length:length];
                    [dic  setObject:value forKey:keys[i]];
                }else if([type isEqualToString:YHBASE_SQL_DATATYPE_BOOLEAN]){
                    NSNumber * value = [NSNumber numberWithInt:sqlite3_column_int(stmt, i)];
                    [dic setObject:value forKey:keys[i]];
                }else if([type isEqualToString:YHBASE_SQL_DATATYPE_CURRENCY]){
                    NSNumber * value = [NSNumber numberWithLong:sqlite3_column_int64(stmt, i)];
                    [dic setObject:value forKey:keys[i]];
                }else if([type isEqualToString:YHBASE_SQL_DATATYPE_DATE]){
                    char * cString =(char*)sqlite3_column_text(stmt, i);
                    NSString * value = [NSString stringWithCString:cString?cString:"NULL" encoding:NSUTF8StringEncoding];
                    [dic setObject:value forKey:keys[i]];
                }else if([type isEqualToString:YHBASE_SQL_DATATYPE_DOUBLE]){
                    NSNumber * value = [NSNumber numberWithFloat:sqlite3_column_double(stmt, i)];
                    [dic setObject:value forKey:keys[i]];
                }else if([type isEqualToString:YHBASE_SQL_DATATYPE_FLOAT]){
                    NSNumber * value = [NSNumber numberWithFloat:sqlite3_column_double(stmt, i)];
                    [dic setObject:value forKey:keys[i]];
                }else if([type isEqualToString:YHBASE_SQL_DATATYPE_INTRGER]){
                    
                    NSNumber * value = [NSNumber numberWithInt:sqlite3_column_int(stmt, i)];
                    [dic setObject:value forKey:keys[i]];
                }else if([type isEqualToString:YHBASE_SQL_DATATYPE_REAL]){
                    NSNumber * value = [NSNumber numberWithDouble:sqlite3_column_int(stmt, i)];
                    [dic setObject:value forKey:keys[i]];
                }else if([type isEqualToString:YHBASE_SQL_DATATYPE_SMALLINT]){
                    NSNumber * value = [NSNumber numberWithShort:sqlite3_column_int(stmt, i)];
                    [dic setObject:value forKey:keys[i]];
                }else if([type isEqualToString:YHBASE_SQL_DATATYPE_TEXT]){
                    char * cString =(char*)sqlite3_column_text(stmt, i);
                    NSString * value = [NSString stringWithCString:cString?cString:"NULL" encoding:NSUTF8StringEncoding];
                    [dic setObject:value forKey:keys[i]];
                }else if([type isEqualToString:YHBASE_SQL_DATATYPE_TIME]){
                    char * cString =(char*)sqlite3_column_text(stmt, i);
                    NSString * value = [NSString stringWithCString:cString?cString:"NULL" encoding:NSUTF8StringEncoding];
                    [dic setObject:value forKey:keys[i]];
                }else if([type isEqualToString:YHBASE_SQL_DATATYPE_TIMESTAMP]){
                    NSNumber * value = [NSNumber numberWithLongLong:sqlite3_column_int64(stmt, i)];
                    [dic setObject:value forKey:keys[i]];
                }else if([type isEqualToString:YHBASE_SQL_DATATYPE_VARCHAR]){
                    char * cString =(char*)sqlite3_column_text(stmt, i);
                    NSString * value = [NSString stringWithCString:cString?cString:"NULL" encoding:NSUTF8StringEncoding];
                    [dic setObject:value forKey:keys[i]];
                }
               
            }
             [resultArray addObject:dic];
        }
         sqlite3_finalize(stmt);
        stmt=nil;
        complete(resultArray,nil);
    }
}
//獲取表中全部字段名和類型
-(NSArray<NSDictionary *> *)getTheTableAllKeys:(NSString *)tableName{
    NSMutableArray * array = [[NSMutableArray alloc]init];
    NSString * getColumn = [NSString stringWithFormat:@"PRAGMA table_info(%@)",tableName];
    sqlite3_stmt *statement;
    sqlite3_prepare_v2(_sqlite3_db, [getColumn UTF8String], -1, &statement, nil);
    while (sqlite3_step(statement) == SQLITE_ROW) {
        char *nameData = (char *)sqlite3_column_text(statement, 1);
        NSString *columnName = [[NSString alloc] initWithUTF8String:nameData];
        char *typeData = (char *)sqlite3_column_text(statement, 2);
        NSString *columntype = [NSString stringWithCString:typeData encoding:NSUTF8StringEncoding];
        NSDictionary * dic = @{columnName:columntype};
        [array addObject:dic];
    }
     sqlite3_finalize(statement);
    statement=nil;
    return array;
}

 

5.錯誤信息類能夠將數據庫操做中的異常拋出提示開發者

YHBaseSQLError.h

/**
 *異常的提示信息
 */
__PROPERTY_NO_STRONG__(NSString *, errorInfo);
/**
 *異常的對應code碼
 */
__PROPERTY_NO_ASSIGN__(NSInteger, errorCode);

 

還有一個頭文件中定義了sqlite數據庫支持的數據類型和排序宏定義:

YHBaseSQLTypeHeader.h

#define YHBASE_SQL_DATATYPE_SMALLINT @"smallint" //short
#define YHBASE_SQL_DATATYPE_INTRGER @"integer"    //int
#define YHBASE_SQL_DATATYPE_REAL @"real"          //實數
#define YHBASE_SQL_DATATYPE_FLOAT @"float"        //float
#define YHBASE_SQL_DATATYPE_DOUBLE @"double"      //double
#define YHBASE_SQL_DATATYPE_CURRENCY @"currency"  //long
#define YHBASE_SQL_DATATYPE_VARCHAR @"varchar"    //char
#define YHBASE_SQL_DATATYPE_TEXT @"text"          //string
#define YHBASE_SQL_DATATYPE_BINARY @"binary"      //二進制
#define YHBASE_SQL_DATATYPE_BLOB @"blob"          //長二進制
#define YHBASE_SQL_DATATYPE_BOOLEAN @"boolean"    //bool
#define YHBASE_SQL_DATATYPE_DATE @"date"          //日期
#define YHBASE_SQL_DATATYPE_TIME @"time"          //時間
#define YHBASE_SQL_DATATYPE_TIMESTAMP @"timestamp"//時間戳

#define YHBASE_SQL_ORDERTYPE_ASC @"asc" //升序
#define YHBASE_SQL_ORDERTYPE_DESC @"desc" //降序

 

4、使用

        在使用時,直接調用context的相應方法操做數據庫便可,例如:

YHBaseSQLiteContext * context = [YHBaseSQLiteManager openSQLiteWithName:@"testDataBase"];
    if (context) {
        [context selectKeys:nil fromTable:@"MySQL" orderBy:@"age" orderType:YHBASE_SQL_ORDERTYPE_DESC whileStr:@"age>18" callBack:^(NSArray<NSDictionary *> *dataArray, YHBaseSQLError *error) {
            NSLog(@"%@",dataArray);
            NSLog(@"%@",error.errorInfo);
            [context closeContext];
        }];
    }

 

上面的代碼將查詢textDataBase數據庫中MySQL表裏全部age列大於18的數據,並按照age從小到大進行排序,數據結果在回調的dataArray中。

外:完整的代碼在下面的git地址中,這個git項目是一個基礎的開發框架,裏面封裝了許多開發和調試經常使用功能,代碼不完善之處,但願多多交流,QQ316045346.

git:https://github.com/ZYHshao/YHBaseFoundationTest

 

專一技術,熱愛生活,交流技術,也作朋友。

——琿少 QQ羣:203317592

相關文章
相關標籤/搜索