iOS笔记

iOS CouchBaseLite的简单封装和简单使用

2017-11-14  本文已影响161人  lxiaok

简介

现在数据库方面的技术很多,也很成熟.但是很多公司也会有很奇怪的需求,明确你要使用什么技术.在数据量很多的时候,不能使用传统数据库的情况下,CouchBaseLite是一个很不错的选择.最起码比本地存储之类的方便,快捷,可以存储数据量比较大的数据,使用方法有点类似数据库.也称作NoSQL的存储方式.
Couchbase Lite 是一个为满足在线和离线的移动应用所开发的超轻量的,可靠的,并且安全的JSON数据库。即使在最不确定的网络条件下,亦可以给您的移动应用提供富有成效的和可靠的信誉。除此之外,’同步门户’功能亦可以提供协作, 社交互动或者是用户的更新。
官方DemoGitHub地址

环境配置

直通车(方便大家直接访问~)
或者按照下面的方法:

image image

里面全部有介绍,怎么大家环境和使用方法.大家查看对应的说明搭建好环境就可以尝试使用了.


image

我的环境配置完成如下图(Xcode 9新建项目报错看最下面)


image

还得配置一些-objc


image 这些弄完就可以尝试编写了.

测试

我是直接基于原来的进行了一些简单的封装,在这里感谢@天梯传说@汪司机,给我很大的帮助.

/*打开或者创建数据库(一般在APPdelegate中)*/
    [DatabaseSetupUtil databaseOpenOrCreate];
#define UserDataPackageCollectionName @"UserDataPackage"
/**
 用户资料model实体
 作用: 主要是存储一些用户信息
 */
@interface UserDataDBModel : DBModelBase
/*-----可以定义字典或者数组类型,demo不做举例------*/
@property (nonatomic,strong) NSString* resident;     //居民姓名
@property (nonatomic,strong) NSString* mobile;      //居民手机号码
@property (nonatomic,strong) NSString* idno;        //居民身份证号码
@property (nonatomic,strong) NSNumber* status;       //状态:1、未上传,2、已上传
@property (nonatomic,strong) NSString* note;      //备注
@property (nonatomic,strong) NSString* crtime;  //创建时间

//根据实体id获取包数据
+ (UserDataDBModel*)getModelByPackageID:(NSString*)reportId;
//根据上上传状态值获取包数据(根据时间排序)
+ (NSArray*)getModelsByStatus:(NSNumber*)status;
//获取所有包数据(根据时间排序)
+ (NSArray*)getAllModels;

.m文件

- (instancetype)init
{
    self = [super init];
    if (self) {
        //文档所属的记录集
        self.collection = UserDataPackageCollectionName;
    }
    return self;
}

- (id)mutableCopy {
    UserDataDBModel* model = [[UserDataDBModel alloc] init];
    //这三个是必须的字段
    model._id = [self._id mutableCopy];
    model._rev = [self._rev mutableCopy];
    model.collection = [self.collection mutableCopy];
//中间代码省略...
    
    return model;
}

//实体转词典
- (NSDictionary*)toDictionary {
    NSMutableDictionary* dic = [NSMutableDictionary dictionary];
//中间代码省略...
    }

//词典转实体
+ (UserDataDBModel*)fromDictionary:(NSDictionary*)dictionary {
    UserDataDBModel* ret = [[UserDataDBModel alloc] init];
//中间代码省略...
}
    
   
#pragma mark -- 扩展方法

//根据体检报告id获取体检报告
+ (UserDataDBModel*)getModelByPackageID:(NSString*)reportId {
   //中间代码省略
}

//根据状态值获取体检报告
+ (NSArray*)getModelsByStatus:(NSNumber*)status {
  //中间代码省略
}

//获取所有体检报告
+ (NSArray*)getAllModels {
//中间代码省略
}
#import "DatabaseSetupUtil.h"
#import "UserDataDBModel.h"

实现下面方法即可

//1.增加数据
- (void)addUserData {
    _model = [[UserDataDBModel alloc] init];
    _model.resident = @"张三";
    _model.mobile = @"123456789111";
    _model.idno = @"546456456575675";
    _model.note = @"假设是资料";
    _model.status = @0;
    _model.crtime = [self getCurrentUTCTime];
}

//保存
- (void)saveDate {
    if(![UserDataDBModel createDocument:_model]) {
        //失败
    }
    else {
        //成功
        NSArray* updateDatas = [UserDataDBModel getModelsByStatus:@0];
        for (UserDataDBModel* model in updateDatas) {
            NSLog(@"文档唯一性id: %@",model._id);
        }
    }
}

至于剩下的更新和删除的操作都是很简单的事情,直接DBModelBase父类的方法或者在model中重写一下父类的方法.

整体框架

[图片上传失败...(image-ad9ad9-1510651510810)]

下面的主要的.h文件的代码.
DBManager.h

/* 数据库 */
@property(strong,nonatomic,readonly) CBLDatabase*
database;

/* 是否启用数据库加密,默认不启用 */
@property(nonatomic) BOOL encrypt;

/**
 *  获取单例管理器对象
 */
+ (DBManager*)shareInstance;

/**
 *  根据数据库存放的路径以及数据库名字创建数据库
 * 参数 path :数据库存放的路径
 * 参数 name :数据库存放的路径
 * 返回值 :如果创建成功或者指定的路径已经存在指定名字的数据库则返回YES,否则返回NO
 */
-(BOOL)createDBWithPath:(NSString*)path  name:(NSString*)name;

/**
 *  根据数据库存放的路径以及数据库名字打开数据库
 * 参数 path :数据库存放的路径
 * 参数 name :数据库存放的路径
 * 返回值 :如果打开成功返回YES,否则返回NO
 */
-(BOOL)openDBWithPath:(NSString*)path  name:(NSString*)name;

/**
 *  删除数据库(必须先打开数据库才能执行删除操作)
 * 参数 path :数据库存放的路径
 * 参数 name :数据库存放的路径
 * 返回值 :如果如果成功或者不存在指定的路径指定名字的数据库则返回YES,否则返回NO
 */
-(BOOL)deleteDB;

/**
 *  执行事务性操作
 * 参数 block :事务block,一旦该block返回No即会执行回滚操作,返回Yes表示事务执行完成
 * 返回值 :如果成功则返回YES,否则返回NO
 */
- (BOOL)inTransaction: (BOOL(^)(void))block;

/**
 *  执行事务性操作(异步模式)
 * 参数 block :事务block,一旦该block返回No即会执行回滚操作,返回Yes表示事务执行完成
 * 参数 competition :完成回调block ,如果成功则返回YES,否则返回NO
 */
- (void)inTransaction: (BOOL(^)(void))block competition:(void (^)(BOOL result))competition;

SingleJobQueue.h

/**
 *  获取单例对象
 */
+ (SingleJobQueue*)shareInstance;

/**
 *  以block方式运行工作任务
 *
 *  @param jobBlock 工作任务block
 */
- (void)runWithJobBlock:(void (^)(void))jobBlock;

/**
 *  以block方式异步运行工作任务(不要问我为什么没有同步~)
 *
 *  @param jobBlock 工作任务block
 *  @param competition 完成回调block
 */
- (void)runAsyncJobWithJobBlock:(void (^)(void))jobBlock competition:(void (^)(void))competition;

DBModelBase.h

@property(strong,nonatomic) NSString* _id; //文档唯一性id
@property(strong,nonatomic) NSString* _rev; //文档版本
@property(strong,nonatomic) NSString* collection; //文档所属的记录集
@property(strong,nonatomic) NSMutableDictionary* extendFields;  //动态扩展字段

//实体转词典,子类必须重写
- (NSDictionary*)toDictionary;

//词典转实体
+ (id)fromDictionary:(NSDictionary*)dictionary;

//转换成服务端JSON
- (NSData*)toServerJSON;

/**
 *  根据指定的实体对象创建一个文档
 * 参数 model :继承自实体基类的具体实体实例
 * 返回值 :如果创建成功则返回文档id,否则返回nil
 */
+(NSString*)createDocument:(id)model;

/**
 *  根据指定的实体对象创建一个文档(异步模式)
 * 参数 model :继承自实体基类的具体实体实例
 * 参数 competition :完成回调block ,如果创建成功则返回文档id,否则返回nil
 */
+(void)createDocument:(id)model competition:(void (^)(NSString* docId))competition;

/**
 *  根据指定的实体对象创建一个文档(适合于在事务中执行)
 * 参数 model :继承自实体基类的具体实体实例
 * 返回值 :如果创建成功则返回文档id,否则返回nil
 */
+(NSString*)createDocumentForTransaction:(id)model;

/**
 *  删除指定id的文档
 * 参数 documentId :文档id
 * 返回值 :如果创建成功则返回YES,否则返回NO
 */
+(BOOL)deleteDocumentWithId:(NSString*)documentId;

/**
 *  删除指定id的文档(异步模式)
 * 参数 documentId :文档id
 * 参数 competition :完成回调block ,如果创建成功则返回YES,否则返回NO
 */
+(void)deleteDocumentWithId:(NSString*)documentId competition:(void (^)(BOOL result))competition;

/**
 *  删除指定id的文档(适合于在事务中执行)
 * 参数 documentId :文档id
 * 返回值 :如果创建成功则返回YES,否则返回NO
 */
+(BOOL)deleteDocumentForTransactionWithId:(NSString*)documentId;


/**
 *  根据指定的实体对象更新符合条件的文档
 * 参数 model :条件参数
 * 参数 newModel :新的文档值参数,继承自实体基类的具体实体实例
 * 返回值 :如果创建成功则返回YES,否则返回NO
 */
+(BOOL)updateDocument:(NSPredicate*)where newModel: (id) newModel;

/**
 *  根据指定的实体对象更新符合条件的文档(异步模式)
 * 参数 model :条件参数
 * 参数 newModel :新的文档值参数,继承自实体基类的具体实体实例
 * 参数 competition :完成回调block ,如果创建成功则返回YES,否则返回NO
 */
+(void)updateDocument:(NSPredicate*)where newModel: (id) newModel competition:(void (^)(BOOL result))competition;

/**
 *  根据指定的实体对象更新符合条件的文档
 * 参数 model :条件参数
 * 参数 newModel :新的文档值参数,继承自实体基类的具体实体实例
 * 返回值 :如果创建成功则返回YES,否则返回NO
 */
+(BOOL)updateDocumentForTransaction:(NSPredicate*)where newModel: (id) newModel;

/**
 *  根据指定的文档id查询文档
 * 参数 documentId :文档id
 * 返回值 :如果查询成功则返回继承自实体基类的具体实体实例,否则返回nil
 */
+(id)getDocumentWithId:(NSString*)documentId;

/**
 *  根据指定的文档id查询文档(异步模式)
 * 参数 documentId :文档id
 * 参数 competition :完成回调block,如果查询成功则返回继承自实体基类的具体实体实例,否则返回nil
 */
+(void)getDocumentWithId:(NSString*)documentId competition:(void (^)(id doc))competition;

/**
 *  根据指定的文档id查询文档(适合于在事务中执行)
 * 参数 documentId :文档id
 * 返回值 :如果查询成功则返回继承自实体基类的具体实体实例,否则返回nil
 */
+(id)getDocumentForTransactionWithId:(NSString*)documentId;

/**
 *  根据指定的实体对象获取符合条件的文档
 * 参数 select :获取字段参数
 * 参数 where :条件参数
 * 参数 orderBy :排序参数
 * 返回值 :如果查询成功则返回继承自实体基类的具体实体实例数组,否则返回nil
 */
+(NSArray*)getDocumentWithSelect: (nullable NSArray*)select where:(NSPredicate*)where orderBy:(nullable NSArray*)orderBy;

/**
 *  根据指定的实体对象获取符合条件的文档(异步模式)
 * 参数 select :获取字段参数
 * 参数 where :条件参数
 * 参数 orderBy :排序参数
 * 参数 competition :完成回调block,如果查询成功则返回继承自实体基类的具体实体实例数组,否则返回nil
 */
+(void)getDocumentWithSelect: (nullable NSArray*)select where:(NSPredicate*)where orderBy:(nullable NSArray*)orderBy competition:(void (^)(NSArray*))competition;

/**
 *  根据指定的实体对象获取符合条件的文档(适合于在事务中执行)
 * 参数 select :获取字段参数
 * 参数 where :条件参数
 * 参数 orderBy :排序参数
 * 返回值 :如果查询成功则返回继承自实体基类的具体实体实例数组,否则返回nil
 */
+(NSArray*)getDocumentForTransactionWithSelect: (nullable NSArray*)select where: (NSPredicate*)where orderBy:(nullable NSArray*)orderBy;

/**
 *  根据指定的实体对象获取符合条件的文档
 * 参数 select : 获取字段参数
 * 参数 where : 条件参数
 * 参数 orderBy : 排序参数
 * 参数 skip : 跳过多少条
 * 参数 limit : 读取多少条
 * 返回值 :如果查询成功则返回继承自实体基类的具体实体实例数组,否则返回nil
 */
+(NSArray*)getDocumentWithSelect: (nullable NSArray*)select where:(NSPredicate*)where orderBy:(nullable NSArray*)orderBy skip:(NSInteger)skip limit:(NSInteger)limit;

/**
 *  根据指定的实体对象获取符合条件的文档(异步模式)
 * 参数 select : 获取字段参数
 * 参数 where : 条件参数
 * 参数 orderBy : 排序参数
 * 参数 skip : 跳过多少条
 * 参数 limit : 读取多少条
 * 参数 competition :完成回调block,如果查询成功则返回继承自实体基类的具体实体实例数组,否则返回nil
 */
+(void)getDocumentWithSelect: (nullable NSArray*)select where:(NSPredicate*)where orderBy:(nullable NSArray*)orderBy skip:(NSInteger)skip limit:(NSInteger)limit competition:(void (^)(NSArray*))competition;

/**
 *  根据指定的实体对象获取符合条件的文档(适合于在事务中执行)
 * 参数 select : 获取字段参数
 * 参数 where : 条件参数
 * 参数 orderBy : 排序参数
 * 参数 skip : 跳过多少条
 * 参数 limit : 读取多少条
 * 返回值 :如果查询成功则返回继承自实体基类的具体实体实例数组,否则返回nil
 */
+(NSArray*)getDocumentForTransactionWithSelect: (nullable NSArray*)select where:(NSPredicate*)where orderBy:(nullable NSArray*)orderBy skip:(NSInteger)skip limit:(NSInteger)limit;

上面的主要是封装的部分方法和文件说明
具体的请查看demo

小结

这个CouchBaseLite个人觉得还是蛮好用的,简单粗暴...,和以往的数据库操作基本一样,也算是比较轻量级的存储了.
上面主要是自己的一些理解的封装,还有很多需要完善,目前只是简单的实现了部分功能,这个后面会逐渐完善的.有什么写错的,请大家指出,一起讨论.

话外篇

Xcode 9的,新建项目会报错,大家就按照下图取消这个就好啦


image
上一篇下一篇

猜你喜欢

热点阅读