摘要: iOS中sqlite3框架可以很好的对sqlite数据库进行支持,通过面向对象的封装,可以更易于开发者使用。

使用iOS原生sqlite3框架对sqlite数据库进行操作

一、引言

sqlite数据库是一种小型数据库,由于其小巧与简洁,在移动开发领域应用深广,sqlite数据库有一套完备的sqlite语句进行管理操作,一些常用的语句和可视化的开发工具在上篇博客中有介绍,地址如下:

sqlite数据库常用语句及可视化工具介绍:http://my.oschina.net/u/2340880/blog/600820

在iOS的原生开发框架中可以对sqlite数据库进行很好的支持,这个框架中采用C风格且通过指针移动进行数据的操作,使用起来有些不便,我们可以对一些数据库的常用操作进行一些面向对象的封装。

二、libsqlite3系统库中操作数据库的常用方法

libsqlite3是对sqlite数据库进行操作的系统库,在使用前,我们需要先导入,点击Xcode的Build Phases标签,展开Link Binary With Libraries,点击+号,在弹出的窗口中搜索libsqlite3.0,将其导入进工程,过程如下图:

在需要操作sqlite数据的文件中导入如下头文件:

  1. #import <sqlite3.h>

数据库文件的操作是由一个sqlite3类型的指针操作管理的,如下方法进行数据库的打开:

  1. sqlite3 *sqlite
  2. sqlite3_open(dataBaePath, &sqlite)

sqlite3_open方法返回一个int值,实际上,在使用libsqlite3框架中的大多方法时都会返回一个int值,这个int值代表着方法执行的相应结果状态,这些状态再sqlite3.h文件中通过宏来定义,列举如下:

  1. #define SQLITE_OK           0   //操作成功
  2. /* 以下是错误代码 */
  3. #define SQLITE_ERROR        1   /* SQL数据库错误或者丢失*/
  4. #define SQLITE_INTERNAL     2   /* SQL内部逻辑错误 */
  5. #define SQLITE_PERM         3   /* 没有访问权限 */
  6. #define SQLITE_ABORT        4   /* 回调请求终止 */
  7. #define SQLITE_BUSY         5   /* 数据库文件被锁定 */
  8. #define SQLITE_LOCKED       6   /* 数据库中有表被锁定 */
  9. #define SQLITE_NOMEM        7   /* 分配空间失败 */
  10. #define SQLITE_READONLY     8   /* 企图向只读属性的数据库中做写操作 */
  11. #define SQLITE_INTERRUPT    9   /* 通过sqlite3_interrupt()方法终止操作*/
  12. #define SQLITE_IOERR       10   /* 磁盘发生错误 */
  13. #define SQLITE_CORRUPT     11   /* 数据库磁盘格式不正确 */
  14. #define SQLITE_NOTFOUND    12   /* 调用位置操作码 */
  15. #define SQLITE_FULL        13   /* 由于数据库已满造成的添加数据失败 */
  16. #define SQLITE_CANTOPEN    14   /* 不法打开数据库文件 */
  17. #define SQLITE_PROTOCOL    15   /* 数据库锁协议错误 */
  18. #define SQLITE_EMPTY       16   /* 数据库为空 */
  19. #define SQLITE_SCHEMA      17   /* 数据库模式更改 */
  20. #define SQLITE_TOOBIG      18   /* 字符或者二进制数据超出长度 */
  21. #define SQLITE_CONSTRAINT  19   /* 违反协议终止 */
  22. #define SQLITE_MISMATCH    20   /* 数据类型不匹配 */
  23. #define SQLITE_MISUSE      21   /* 库使用不当 */
  24. #define SQLITE_NOLFS       22   /* 使用不支持的操作系统 */
  25. #define SQLITE_AUTH        23   /* 授权拒绝 */
  26. #define SQLITE_FORMAT      24   /* 辅助数据库格式错误 */
  27. #define SQLITE_RANGE       25   /* sqlite3_bind 第二个参数超出范围 */
  28. #define SQLITE_NOTADB      26   /* 打开不是数据库的文件 */
  29. #define SQLITE_NOTICE      27   /* 来自sqlite3_log()的通知 */
  30. #define SQLITE_WARNING     28   /* 来自sqlite3_log() 的警告*/
  31. #define SQLITE_ROW         100  /* sqlite3_step() 方法准备好了一行数据 */
  32. #define SQLITE_DONE        101  /* sqlite3_step() 已完成执行*/

执行非查询类的语句,例如创建,添加,删除等操作,使用如下方法:

  1. char * err;
  2. sqlite3 *sql;
  3. sqlite3_exec(sql, sqlStr, NULL, NULL, &err);

sqlite3_exec方法中第一个参数为成功执行了打开数据库操作的sqlite3指针,第二个参数为要执行的sql语句,最后一个参数为错误信息字符串。

执行查询语句的方法比较复杂,通过如下方法:

  1.     sqlite3 * sqlite;
  2.     sqlite3_stmt *stmt =nil;
  3.     int code = sqlite3_prepare_v2(sqlite, sqlStr, -1, &stmt, NULL);
  4.      while (sqlite3_step(stmt)==SQLITE_ROW) {
  5.          char * cString =(char*)sqlite3_column_text(stmt, 0);
  6.          NSString * value = [NSString stringWithCString:cString?cString:"NULL" encoding:NSUTF8StringEncoding];
  7.          NSNumber * value = [NSNumber numberWithLongLong:sqlite3_column_int64(stmt, 1)];
  8.         }
  9.          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指针进行关闭。

三、面向对象的sqlite数据库操作框架封装

网上不乏有许多优秀的第三方sqlite数据库使用框架,FFDM就是其中之一,并且apple自带的coreData也十分优秀。这篇博客中所述内容并不全面,代码也并不十分完善健壮,封装出来的代码除了能够完成基本的数据库操作外,更多主要是对设计思路的示例。

1.面向对象的sqlite管理类的设计思路

为了便于使用,在设计时,我们尽量将libsqlite3中的方法不暴漏在使用层,通过面向应用的接口来进行方法的设计,设计思路类图如下:

图中,文件管理中心对文件进行存取删改管理,不暴漏在外,数据库管理中心负责对数据库的创建,删除打开等操作,具体的数据操作由数据库操作对象来完成。

2.文件管理中心方法的编写

文件管理中心主要负责对数据库文件的存取,可以实现如下方法:

YHBaseCecheCenter.h

  1. /**
  2.  *  @brief 获取数据库方法的地址
  3.  *
  4.  *  @return 地址字符串
  5.  *
  6.  */
  7. -(NSString *)getDataBaseFilePath;
  8. /**
  9.  *  @brief 获取某个数据库的大小
  10.  *
  11.  *  @param name 数据库名称
  12.  *
  13.  *  @return 文件大小 单位M
  14.  *
  15.  */
  16. -(float)getSizeFromDataBaseName:(NSString *)name;

YHBaseCecheCenter.m

  1. -(NSString *)getDataBaseFilePath{
  2.     return NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
  3. }
  4. -(float)getSizeFromDataBaseName:(NSString *)name{
  5.     NSString * path = [NSString stringWithFormat:@"/%@/%@",NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject,name];
  6.     return  [self fileSizeAtPath:path]/(1024.0*1024.0);
  7. }
  8. //获取文件大小
  9. - (long long) fileSizeAtPath:(NSString*) filePath{
  10.     NSFileManager* manager = [NSFileManager defaultManager];
  11.     if ([manager fileExistsAtPath:filePath]){
  12.         return [[manager attributesOfItemAtPath:filePath error:nil] fileSize];
  13.     }
  14.     return 0;
  15. }

在iOS系统中因为其沙盒结构的限制,数据库必须方法documents目录下才能正常打开使用。

3.数据库管理中心的设计

数据库管理中心主要负责对数据库的宏观操作,采用类方法的设计模式,如下

YHBaseSQLiteManager.h

  1. /**
  2.  *  @brief 打开一个数据库 如果不存在则会创建
  3.  *
  4.  *  @param name 数据库名称
  5.  *
  6.  *  @return 数据库操作对象 如果创建失败会返回nil
  7.  *
  8.  */
  9. +(YHBaseSQLiteContext *)openSQLiteWithName:(NSString *)name;
  10. /**
  11.  *  @brief 获取数据库文件的大小 单位M
  12.  *
  13.  *  @param dataBase 数据库上下文对象
  14.  *
  15.  *  @return 数据库文件大小
  16.  */
  17. +(float)getSizeOfDataBase:(YHBaseSQLiteContext *)dataBase;
  18. /**
  19.  *  @brief 获取数据库文件的大小 单位M
  20.  *
  21.  *  @param dataBaseName 数据库名称
  22.  *
  23.  *  @return 数据库文件大小
  24.  */
  25. +(float)getSizeOfDataBaseName:(NSString *)dataBaseName;
  26. /**
  27.  *  @brief 删除所有数据库
  28.  *
  29.  */
  30. +(void)removeDataBase;

YHBaseSQLiteManager.m

  1. +(YHBaseSQLiteContext *)openSQLiteWithName:(NSString *)name{
  2.     
  3.     NSString * path =  [[YHBaseCecheCenter sharedTheSingletion]getDataBaseFilePath];
  4.     YHBaseSQLiteContext * context = [[YHBaseSQLiteContext alloc]init];
  5.     context.name = name;
  6.     BOOL success = [context openDataBaeWithName:[NSString stringWithFormat:@"%@/%@",path,name]];
  7.     if (success) {
  8.         return context;
  9.     }else{
  10.         return nil;
  11.     }
  12. }
  13. +(float)getSizeOfDataBase:(YHBaseSQLiteContext *)dataBase{
  14.     return [[YHBaseCecheCenter sharedTheSingletion]getSizeFromDataBaseName:dataBase.name];
  15. }
  16. +(float)getSizeOfDataBaseName:(NSString *)dataBaseName{
  17.     return [[YHBaseCecheCenter sharedTheSingletion]getSizeFromDataBaseName:dataBaseName];
  18. }
  19. +(void)removeDataBase{
  20.     NSString * path =  [[YHBaseCecheCenter sharedTheSingletion]getDataBaseFilePath];
  21.     return [[YHBaseCecheCenter sharedTheSingletion]removeCacheFromPath:path];
  22. }

4.数据库操作对象

将操作数据库的核心方法封装在这个类中:

YHBaseSQLiteContext.h

  1. /**
  2.  *操作的数据库名称
  3.  */
  4. @property(nonatomic,strong)NSString * name;
  5. /**
  6.  *内含sqlite3 对象
  7.  */
  8. @property(nonatomic,assign)sqlite3 * sqlite3_db;
  9. /**
  10.  * @brief 打开一个数据库 不存在则创建
  11.  *
  12.  * @param path 数据库路径
  13.  *
  14.  * @return 是否操作成功
  15.  */
  16. -(BOOL)openDataBaeWithName:(NSString *)path;
  17. /**
  18.  *  @brief 再数据库中创建一张表 如果已经存在 会返回错误信息
  19.  *
  20.  *  @param name 表的名称
  21.  *
  22.  *  @prarm dic 表中的键 其中字典中需传入 键名:类型  类型的宏定义在YHBaseSQLTypeHeader.h中
  23.  *
  24.  *  @param callBack 结果回调
  25.  */
  26. -(void)createTableWithName:(NSString *)name
  27.             keysDictionary:(NSDictionary<NSString*,NSString*> *) dic
  28.                   callBack:(void (^)(YHBaseSQLError * error))complete;
  29. /**
  30.  *  @brief 向表中添加一条数据
  31.  *
  32.  *  @param dataDic 添加数据的键值对
  33.  *
  34.  *  @param name 插入表的名称
  35.  *
  36.  *  @complete 回调
  37.  */
  38. -(void)insertData:(NSDictionary<NSString *,id>*)dataDic
  39.         intoTable:(NSString *)name
  40.          callBack:(void (^)(YHBaseSQLError * error))complete;
  41. /**
  42.  *  @brief 向表中添加一个键
  43.  *
  44.  *  @param kName 添加的键
  45.  *
  46.  *  @prarm type 类型
  47.  *
  48.  *  @prarm tableName 表名称
  49.  *
  50.  *  @prarm complete 结果回调
  51.  */
  52. -(void)addKey:(NSString *)kName
  53.       keyType:(NSString *)type
  54.     intoTable:(NSString *)tableName
  55.      callBack:(void(^)(YHBaseSQLError *error))complete;
  56. /**
  57.  *  @brief 修改数据
  58.  *
  59.  *  @param dataDic 新的键值
  60.  *
  61.  *  @param wlStr 条件字符串 一般通过主键找到对应数据修改 可以为nil
  62.  *
  63.  *  @param complete 结果回调
  64.  */
  65. -(void)update:(NSDictionary<NSString*,id> *)dataDic
  66.       inTable:(NSString *)tableName
  67.   whileString:(NSString *)wlStr
  68.      callBack:(void(^)(YHBaseSQLError * error))complete;
  69. /**
  70.  *  @brief 删除数据
  71.  *
  72.  *  @param tableName 表名
  73.  *
  74.  *  @param wlStr 条件字符串 一般通过主键找到对应数据删除 可以为nil 不传这个参数将删除所有数据
  75.  *
  76.  */
  77. -(void)deleteDataFromTable:(NSString *)tableName
  78.                whereString:(NSString *)wlStr
  79.                   callBack:(void(^)(YHBaseSQLError * error))complete;
  80. /**
  81.  *  @brief 删除一张表
  82.  *
  83.  *  @param tableName 表名
  84.  *
  85.  */
  86. -(void)dropTable:(NSString *)tableName
  87.         callBack:(void(^)(YHBaseSQLError * error))complete;
  88. /**
  89.  *  @brief 查询数据
  90.  *
  91.  *  @param keys 要查询的键值 及其对应的数据类型 可以为nil则查询全部
  92.  *
  93.  *  @param tableName 表名
  94.  *
  95.  *  @param orderKey 进行排序的键值 可以为nil 则不排序
  96.  *
  97.  *  @param type 排序方式 在YHBaseSQLTypeHeader中有宏定义
  98.  *
  99.  *  @param wlstr 查询条件 同于查询单个数据
  100.  *
  101.  *  @param complete dataArray为查询到的数据 其内为字典
  102.  *
  103.  */
  104. -(void)selectKeys:(NSArray<NSDictionary *> *)keys
  105.         fromTable:(NSString*)tableName
  106.           orderBy:(NSString *)orderKey
  107.         orderType:(NSString *)type
  108.          whileStr:(NSString *)wlstr
  109.          callBack:(void(^)(NSArray<NSDictionary *> * dataArray,YHBaseSQLError * error))complete;
  110. /**
  111.  *  @brief 关闭数据库上下文操作
  112.  *  调用此方法后 这个context对象将不再有效 如果再需要使用 需要YHBaseSQLiteManager中的类方法再次返回
  113.  */
  114. -(void)closeContext;

YHBaseSQLiteContext.m

  1. -(BOOL)openDataBaeWithName:(NSString *)path{
  2.     if (sqlite3_open([path UTF8String], &_sqlite3_db)!=SQLITE_OK) {
  3.         sqlite3_close(_sqlite3_db);
  4.         _sqlite3_db=nil;
  5.         return NO;
  6.     }else{
  7.         return YES;
  8.     }
  9. }
  10. -(void)createTableWithName:(NSString *)name keysDictionary:(NSDictionary<NSString *,NSString *> *)dic callBack:(void (^)(YHBaseSQLError *))complete{
  11.     NSMutableString * keys = [[NSMutableString alloc]init];
  12.     for (int i=0; i<dic.allKeys.count; i++) {
  13.         NSString * key = dic.allKeys[i];
  14.         if (i<dic.allKeys.count-1) {
  15.             [keys appendFormat:@"%@ %@,",key,[dic objectForKey:key]];
  16.         }else{
  17.             [keys appendFormat:@"%@ %@",key,[dic objectForKey:key]];
  18.         }
  19.     }
  20.     NSString * sqlStr = [NSString stringWithFormat:@"create table %@(%@)",name,keys];
  21.     [self runSQL:sqlStr callBack:^(YHBaseSQLError * error) {
  22.         
  23.         if (complete) {
  24.             complete(error);
  25.         }
  26.         
  27.     }];
  28. }
  29. -(void)insertData:(NSDictionary<NSString *,id> *)dataDic intoTable:(NSString *)name callBack:(void (^)(YHBaseSQLError *))complete{
  30.     NSMutableString * keys = [[NSMutableString alloc]init];
  31.     NSMutableString * values = [[NSMutableString alloc]init];
  32.     for (int i=0; i<dataDic.allKeys.count; i++) {
  33.         NSString * key = dataDic.allKeys[i];
  34.         if (i<dataDic.count-1) {
  35.             [keys appendFormat:@"%@,",key];
  36.             [values appendFormat:@"\"%@\",",[dataDic objectForKey:key]];
  37.         }else{
  38.             [keys appendFormat:@"%@",key];
  39.             [values appendFormat:@"\"%@\"",[dataDic objectForKey:key]];
  40.         }
  41.     }
  42.     NSString * sqlStr = [NSString stringWithFormat:@"insert into %@(%@) values(%@)",name,keys,values];
  43.     [self runSQL:sqlStr callBack:^(YHBaseSQLError *error) {
  44.         
  45.         if (complete) {
  46.             complete(error);
  47.         }
  48.         
  49.     }];
  50. }
  51. -(void)addKey:(NSString *)kName keyType:(NSString *)type intoTable:(NSString *)tableName callBack:(void (^)(YHBaseSQLError *))complete{
  52.     NSString * sqlStr = [NSString stringWithFormat:@"alter table %@ add %@ %@",tableName,kName,type];
  53.     [self runSQL:sqlStr callBack:^(YHBaseSQLError *error) {
  54.         if (complete) {
  55.             complete(error);
  56.         }
  57.     }];
  58. }
  59. -(void)update:(NSDictionary<NSString *,id> *)dataDic inTable:(NSString *)tableName whileString:(NSString *)wlStr callBack:(void (^)(YHBaseSQLError *))complete{
  60.     NSMutableString * sqlStr = [[NSMutableString alloc]init];
  61.     [sqlStr appendFormat:@"update %@ set ",tableName];
  62.     for (int i=0; i<dataDic.allKeys.count; i++) {
  63.         NSString * key = dataDic.allKeys[i];
  64.         if (i<dataDic.allKeys.count-1) {
  65.             [sqlStr appendFormat:@"%@=\"%@\",",key,[dataDic objectForKey:key]];
  66.         }else{
  67.             [sqlStr appendFormat:@"%@=\"%@\"",key,[dataDic objectForKey:key]];
  68.             if (wlStr!=nil) {
  69.                 [sqlStr appendFormat:@" where %@",wlStr];
  70.             }
  71.         }
  72.     }
  73.     [self runSQL:sqlStr callBack:^(YHBaseSQLError *error) {
  74.         if (complete) {
  75.             complete(error);
  76.         }
  77.     }];
  78. }
  79. -(void)deleteDataFromTable:(NSString *)tableName whereString:(NSString *)wlStr callBack:(void (^)(YHBaseSQLError *))complete{
  80.     NSMutableString * sqlStr = [[NSMutableString alloc]init];
  81.     [sqlStr appendFormat:@"delete from %@",tableName];
  82.     if (wlStr!=nil) {
  83.         [sqlStr appendFormat:@" where %@",wlStr];
  84.     }
  85.     [self runSQL:sqlStr callBack:^(YHBaseSQLError *error) {
  86.         if (complete) {
  87.             complete(error);
  88.         }
  89.     }];
  90. }
  91. -(void)dropTable:(NSString *)tableName callBack:(void (^)(YHBaseSQLError *))complete{
  92.     NSString * sqlStr = [NSString stringWithFormat:@"drop table %@",tableName];
  93.     [self runSQL:sqlStr callBack:^(YHBaseSQLError *error) {
  94.         if (complete) {
  95.             complete(error);
  96.         }
  97.     }];
  98. }
  99. -(void)selectKeys:(NSArray<NSDictionary *> *)keys fromTable:(NSString *)tableName orderBy:(NSString *)orderKey orderType:(NSString *)type whileStr:(NSString *)wlstr callBack:(void (^)(NSArray<NSDictionary *> *, YHBaseSQLError *))complete{
  100.     NSMutableString * sqlStr = [[NSMutableString alloc]init];
  101.     [sqlStr appendFormat:@"select"];
  102.     if (keys==nil||keys.count==0) {
  103.         [sqlStr appendFormat:@" * from %@",tableName];
  104.     }else{
  105.         for (int i=0; i<keys.count; i++) {
  106.             if (i<keys.count-1) {
  107.                 [sqlStr appendFormat:@" %@,",keys[i].allKeys.firstObject];
  108.             }else{
  109.                 [sqlStr appendFormat:@" %@ from %@",keys[i].allKeys.firstObject,tableName];
  110.             }
  111.             
  112.         }
  113.     }
  114.     if (wlstr) {
  115.         [sqlStr appendFormat:@" where %@",wlstr];
  116.     }
  117.     if (orderKey) {
  118.         [sqlStr appendFormat:@" order by %@",orderKey];
  119.     }
  120.     if (type) {
  121.         [sqlStr appendFormat:@" %@",type];
  122.     }
  123.     NSMutableArray * keysArr = [[NSMutableArray alloc]init];
  124.     NSMutableArray * keysTypeArr = [[NSMutableArray alloc]init];
  125.     if (keys==nil||keys.count==0) {
  126.         NSArray<NSDictionary *> * tmpArr = [self getTheTableAllKeys:tableName];
  127.         for (int i=0; i<tmpArr.count; i++) {
  128.             NSString * key = tmpArr[i].allKeys.firstObject;
  129.             [keysArr addObject:key];
  130.             [keysTypeArr addObject:[tmpArr[i] objectForKey:key]];
  131.         }
  132.     }else{
  133.         for (int i=0; i<keys.count; i++) {
  134.             NSString * key = keys[i].allKeys.firstObject;
  135.             [keysArr addObject:key];
  136.             [keysTypeArr addObject:[keys[i] objectForKey:key]];
  137.         }
  138.     }
  139.     
  140.     [self runSelectSQL:sqlStr withKeys:keysArr withDataType:keysTypeArr callBack:^(NSArray<NSDictionary *> *dataArray, YHBaseSQLError *error) {
  141.         if (complete) {
  142.             complete(dataArray,error);
  143.         }
  144.     }];
  145.    
  146. }
  147. -(void)closeContext{
  148.     sqlite3_close(_sqlite3_db);
  149.     _sqlite3_db = nil;
  150. }
  151. //内部方法 运行创建独立的非查询SQL语句
  152. -(void)runSQL:(NSString *)sql callBack:(void(^)(YHBaseSQLError * error))complete{
  153.     char * err;
  154.     int code = sqlite3_exec(_sqlite3_db, [sql UTF8String], NULL, NULL, &err);
  155.     if (code!=SQLITE_OK) {
  156.         YHBaseSQLError * error = [[YHBaseSQLError alloc]init];
  157.         error.errorInfo = [NSString stringWithCString:err encoding:NSUTF8StringEncoding];
  158.         error.errorCode = code;
  159.         complete(error);
  160.     }else{
  161.         complete(nil);
  162.     }
  163. }
  164. //运行查询语句
  165. -(void)runSelectSQL:(NSString *)sql withKeys:(NSArray *)keys withDataType:(NSArray *)dataType callBack:(void(^)(NSArray<NSDictionary *> * dataArray, YHBaseSQLError * error))complete{
  166.     sqlite3_stmt *stmt =nil;
  167.     int code = sqlite3_prepare_v2(_sqlite3_db, [sql UTF8String], -1, &stmt, NULL);
  168.     if (code!=SQLITE_OK) {
  169.         YHBaseSQLError * error = [[YHBaseSQLError alloc]init];
  170.         error.errorInfo = @"查询失败";
  171.         error.errorCode=code;
  172.         complete(nil,error);
  173.     }else{
  174.         NSMutableArray * resultArray = [[NSMutableArray alloc]init];
  175.         
  176.         while (sqlite3_step(stmt)==SQLITE_ROW) {
  177.             //数据类型的分别解析
  178.             NSMutableDictionary * dic = [[NSMutableDictionary alloc]init];
  179.             for (int i=0; i<dataType.count; i++) {
  180.                 NSString * type = dataType[i];
  181.                 if ([type isEqualToString:YHBASE_SQL_DATATYPE_BINARY]) {
  182.                     int length = sqlite3_column_bytes(stmt, i);
  183.                     const void *data = sqlite3_column_blob(stmt, i);
  184.                     NSData * value = [NSData dataWithBytes:data length:length];
  185.                     [dic  setObject:value forKey:keys[i]];
  186.                 }else if([type isEqualToString:YHBASE_SQL_DATATYPE_BLOB]){
  187.                     int length = sqlite3_column_bytes(stmt, i);
  188.                     const void *data = sqlite3_column_blob(stmt, i);
  189.                     NSData * value = [NSData dataWithBytes:data length:length];
  190.                     [dic  setObject:value forKey:keys[i]];
  191.                 }else if([type isEqualToString:YHBASE_SQL_DATATYPE_BOOLEAN]){
  192.                     NSNumber * value = [NSNumber numberWithInt:sqlite3_column_int(stmt, i)];
  193.                     [dic setObject:value forKey:keys[i]];
  194.                 }else if([type isEqualToString:YHBASE_SQL_DATATYPE_CURRENCY]){
  195.                     NSNumber * value = [NSNumber numberWithLong:sqlite3_column_int64(stmt, i)];
  196.                     [dic setObject:value forKey:keys[i]];
  197.                 }else if([type isEqualToString:YHBASE_SQL_DATATYPE_DATE]){
  198.                     char * cString =(char*)sqlite3_column_text(stmt, i);
  199.                     NSString * value = [NSString stringWithCString:cString?cString:"NULL" encoding:NSUTF8StringEncoding];
  200.                     [dic setObject:value forKey:keys[i]];
  201.                 }else if([type isEqualToString:YHBASE_SQL_DATATYPE_DOUBLE]){
  202.                     NSNumber * value = [NSNumber numberWithFloat:sqlite3_column_double(stmt, i)];
  203.                     [dic setObject:value forKey:keys[i]];
  204.                 }else if([type isEqualToString:YHBASE_SQL_DATATYPE_FLOAT]){
  205.                     NSNumber * value = [NSNumber numberWithFloat:sqlite3_column_double(stmt, i)];
  206.                     [dic setObject:value forKey:keys[i]];
  207.                 }else if([type isEqualToString:YHBASE_SQL_DATATYPE_INTRGER]){
  208.                     
  209.                     NSNumber * value = [NSNumber numberWithInt:sqlite3_column_int(stmt, i)];
  210.                     [dic setObject:value forKey:keys[i]];
  211.                 }else if([type isEqualToString:YHBASE_SQL_DATATYPE_REAL]){
  212.                     NSNumber * value = [NSNumber numberWithDouble:sqlite3_column_int(stmt, i)];
  213.                     [dic setObject:value forKey:keys[i]];
  214.                 }else if([type isEqualToString:YHBASE_SQL_DATATYPE_SMALLINT]){
  215.                     NSNumber * value = [NSNumber numberWithShort:sqlite3_column_int(stmt, i)];
  216.                     [dic setObject:value forKey:keys[i]];
  217.                 }else if([type isEqualToString:YHBASE_SQL_DATATYPE_TEXT]){
  218.                     char * cString =(char*)sqlite3_column_text(stmt, i);
  219.                     NSString * value = [NSString stringWithCString:cString?cString:"NULL" encoding:NSUTF8StringEncoding];
  220.                     [dic setObject:value forKey:keys[i]];
  221.                 }else if([type isEqualToString:YHBASE_SQL_DATATYPE_TIME]){
  222.                     char * cString =(char*)sqlite3_column_text(stmt, i);
  223.                     NSString * value = [NSString stringWithCString:cString?cString:"NULL" encoding:NSUTF8StringEncoding];
  224.                     [dic setObject:value forKey:keys[i]];
  225.                 }else if([type isEqualToString:YHBASE_SQL_DATATYPE_TIMESTAMP]){
  226.                     NSNumber * value = [NSNumber numberWithLongLong:sqlite3_column_int64(stmt, i)];
  227.                     [dic setObject:value forKey:keys[i]];
  228.                 }else if([type isEqualToString:YHBASE_SQL_DATATYPE_VARCHAR]){
  229.                     char * cString =(char*)sqlite3_column_text(stmt, i);
  230.                     NSString * value = [NSString stringWithCString:cString?cString:"NULL" encoding:NSUTF8StringEncoding];
  231.                     [dic setObject:value forKey:keys[i]];
  232.                 }
  233.                
  234.             }
  235.              [resultArray addObject:dic];
  236.         }
  237.          sqlite3_finalize(stmt);
  238.         stmt=nil;
  239.         complete(resultArray,nil);
  240.     }
  241. }
  242. //获取表中所有字段名和类型
  243. -(NSArray<NSDictionary *> *)getTheTableAllKeys:(NSString *)tableName{
  244.     NSMutableArray * array = [[NSMutableArray alloc]init];
  245.     NSString * getColumn = [NSString stringWithFormat:@"PRAGMA table_info(%@)",tableName];
  246.     sqlite3_stmt *statement;
  247.     sqlite3_prepare_v2(_sqlite3_db, [getColumn UTF8String], -1, &statement, nil);
  248.     while (sqlite3_step(statement) == SQLITE_ROW) {
  249.         char *nameData = (char *)sqlite3_column_text(statement, 1);
  250.         NSString *columnName = [[NSString alloc] initWithUTF8String:nameData];
  251.         char *typeData = (char *)sqlite3_column_text(statement, 2);
  252.         NSString *columntype = [NSString stringWithCString:typeData encoding:NSUTF8StringEncoding];
  253.         NSDictionary * dic = @{columnName:columntype};
  254.         [array addObject:dic];
  255.     }
  256.      sqlite3_finalize(statement);
  257.     statement=nil;
  258.     return array;
  259. }

5.错误信息类可以将数据库操作中的异常抛出提示开发者

YHBaseSQLError.h

  1. /**
  2.  *异常的提示信息
  3.  */
  4. __PROPERTY_NO_STRONG__(NSString *, errorInfo);
  5. /**
  6.  *异常的对应code码
  7.  */
  8. __PROPERTY_NO_ASSIGN__(NSInteger, errorCode);

还有一个头文件中定义了sqlite数据库支持的数据类型和排序宏定义:

YHBaseSQLTypeHeader.h

  1. #define YHBASE_SQL_DATATYPE_SMALLINT @"smallint" //short
  2. #define YHBASE_SQL_DATATYPE_INTRGER @"integer"    //int
  3. #define YHBASE_SQL_DATATYPE_REAL @"real"          //实数
  4. #define YHBASE_SQL_DATATYPE_FLOAT @"float"        //float
  5. #define YHBASE_SQL_DATATYPE_DOUBLE @"double"      //double
  6. #define YHBASE_SQL_DATATYPE_CURRENCY @"currency"  //long
  7. #define YHBASE_SQL_DATATYPE_VARCHAR @"varchar"    //char
  8. #define YHBASE_SQL_DATATYPE_TEXT @"text"          //string
  9. #define YHBASE_SQL_DATATYPE_BINARY @"binary"      //二进制
  10. #define YHBASE_SQL_DATATYPE_BLOB @"blob"          //长二进制
  11. #define YHBASE_SQL_DATATYPE_BOOLEAN @"boolean"    //bool
  12. #define YHBASE_SQL_DATATYPE_DATE @"date"          //日期
  13. #define YHBASE_SQL_DATATYPE_TIME @"time"          //时间
  14. #define YHBASE_SQL_DATATYPE_TIMESTAMP @"timestamp"//时间戳
  15. #define YHBASE_SQL_ORDERTYPE_ASC @"asc" //升序
  16. #define YHBASE_SQL_ORDERTYPE_DESC @"desc" //降序

四、使用

在使用时,直接调用context的相应方法操作数据库即可,例如:

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

上面的代码将查询textDataBase数据库中MySQL表里所有age列大于18的数据,并按照age从小到大进行排序,数据结果在回调的dataArray中。

外:完整的代码在下面的git地址中,这个git项目是一个基础的开发框架,里面封装了许多开发和调试常用功能,代码不完善之处,希望多多交流,QQ316045346.

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

使用iOS原生sqlite3框架对sqlite数据库进行操作的更多相关文章

  1. IOS开发-UI学习-sqlite数据库的操作

    IOS开发-UI学习-sqlite数据库的操作 sqlite是一个轻量级的数据库,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了,而且它的处理速度比Mysql.PostgreSQL这 ...

  2. 从C#到Objective-C,循序渐进学习苹果开发(7)--使用FMDB对Sqlite数据库进行操作

    本随笔系列主要介绍从一个Windows平台从事C#开发到Mac平台苹果开发的一系列感想和体验历程,本系列文章是在起步阶段逐步积累的,希望带给大家更好,更真实的转换历程体验.本篇主要开始介绍基于XCod ...

  3. 2014-08-01 ASP.NET中对SQLite数据库的操作——ADO.NET

    今天是在吾索实习的第18天.我主要学习了如何在ASP.NET中对SQLite数据库的操作,其基本操作如下: 添加引用System.Data.SQLite.dll(PS:在网页里面任意找到适合的.NET ...

  4. Laravel框架中的数据库CURD操作、连贯操作、链式操作的用法

    Laravel是一套简洁.优雅的PHP Web开发框架(PHP Web Framework).它可以让你从面条一样杂乱的代码中解脱出来:它可以帮你构建一个完美的网络APP,而且每行代码都可以简洁.富于 ...

  5. iOS学习36数据处理之SQLite数据库

    1. 数据库管理系统 1> SQL语言概述 SQL: SQL是Structured Query Language(结构化查询语言)的缩写.SQL是专为数据库而建立的操作命令集, 是一种功能齐全的 ...

  6. 安卓平台SQLite数据库基础操作总结

    最近学了一些安卓开发,在这里分享一下SQLite数据库的使用相关部分,我使用的工具为Android Studio,后台语言为java: 首先,需要创建一个数据库辅助类DataBaseHelper,用于 ...

  7. iOS sqlite大数据分段加载的实现,sqlite数据库的操作

    数据库管理类(自己封装的,挺简单的) // //  MyDataBaseManger.m //  DB_Test // //  Created by admin on 17/2/7. //  Copy ...

  8. Express框架使用以及数据库公共操作类整理(Win7下的NodeJs)

    具体步骤: 1.安装开发工具WebStorm: 2.安装node/npm(下载地址:https://nodejs.org/download/)选择适合你的xxx.mis安装: 3.安装express框 ...

  9. [转]html5 js 访问 sqlite 数据库的操作类

    本文转自:http://blog.csdn.net/tsxw24/article/details/7613815 webkit 核心的浏览器提供了 3个 api接口,用于访问本地sqlite数据,但使 ...

随机推荐

  1. UML基础知识点

    UML   :   unified Modeling Language  统一建模语言 1.对系统问题进行分析和建模 2.非专利的第三代建模和规约语言 3.UML是一种开放的方法.用于说明.可视化.构 ...

  2. error: could not install *smartsocket* listener: Address already in use 下午8:49 ADB server didn't ACK 下午8:49 * failed to start daemon * 下午8:49 error: cannot connect to daemon

    在终端输入adb命令,出错如下: localhost:work zhangyg$ adb devices List of devices attached adb server version (32 ...

  3. HDU 5187 zhx&#39;s contest(防爆__int64 )

    Problem Description As one of the most powerful brushes, zhx is required to give his juniors n probl ...

  4. IOS版本号被拒的经历

    IOS版本号被拒的经历: 1,登陆方式依赖外部平台 由于我们的APP是仅仅用微博登陆.想做成类似meerkat类型的.也能各种消息都同步微博. 结果当然行不通,这个确实是不听好人言.网上多个人都说过这 ...

  5. c++变量的作用域、生存期和可见性

    局部变量 范围:在一个函数内部定义的变量,作用范围仅仅限于本函数体内. 生存期:程序运行到本函数才会给局部变量分配内存单元.函数运行完成局部变量所占的存储单元就被释放 全局变量 在函数体外部定义的变量 ...

  6. 判断QString是否为纯数字,查找自身最长重复子字符串

    1.判断QString是否为纯数字 bool IsDigitString(QString strSource) { bool bDigit = false; if (strSource.isEmpty ...

  7. [JZOJ 5906] [NOIP2018模拟10.15] 传送门 解题报告(树形DP)

    题目链接: https://jzoj.net/senior/#contest/show/2528/2 题目: 8102年,Normalgod在GLaDOS的帮助下,研制出了传送枪.但GLaDOS想把传 ...

  8. APACHE KYLIN™ 概览(分布式分析引擎)

    Apache Kylin™是一个开源的分布式分析引擎,提供Hadoop/Spark之上的SQL查询接口及多维分析(OLAP)能力以支持超大规模数据,最初由eBay Inc. 开发并贡献至开源社区.它能 ...

  9. xxx while the managed IDbConnection interface was being used: Login failed for user xxx

    Process cube的时候遇到如下错误.   Errors in the high-level relational engine. The following exception occurre ...

  10. Python的Flask框架入门-Ubuntu

    全文请见tuts code:An Introduction to Python's Flask Framework Flask是Python一个小而强大的web框架.学起来简单,用起来也容易,能够帮你 ...