WCDB for iOS/macOS

屏幕快照 2017-09-14 下午4.27.49.png

基本特性

  • 易用,WCDB支持一句代码即可将数据取出并组合为object。
  • WINQ(WCDB语言集成查询):通过WINQ,开发者无须为了拼接SQL的字符串而写一大坨胶水代码。

  • ORM(Object Relational Mapping):WCDB支持灵活、易用的ORM。开发者可以很便捷地定义表、索引、约束,并进行增删改查操作。

[database getObjectsOfClass:WCTSampleConvenient.class
                  fromTable:tableName
                      where:WCTSampleConvenient.intValue>=10
                      limit:20];
  • 高效,WCDB通过框架层和sqlcipher源码优化,使其更高效的表现。
  • 多线程高并发:WCDB支持多线程读与读、读与写并发执行,写与写串行执行。

批量写操作性能测试:

更多关于WCDB的性能数据,请参考benchmark。

  • 完整,WCDB覆盖了数据库相关各种场景的所需功能。

    • 加密:WCDB提供基于SQLCipher的数据库加密。
    • 损坏修复:WCDB内建了Repair Kit用于修复损坏的数据库。
    • 反注入:WCDB内建了对SQL注入的保护。

通过cocoapods安装

  1. 先安装Cocoapods。
  2. 通过 pod repo update 更新WCDB的cocoapods版本。
  3. 在Podfile对应的target中,添加pod 'WCDB',并执行pod install。
  4. 在项目中使用CocoaPods生成的.xcworkspace运行工程。
  5. 在你的代码文件头引入头文件#import <WCDB/WCDB.h>。
  6. 由于WCDB是基于Objective-C++,因此需要将引用WCDB的源文件后缀.m改为.mm。

在这里需要说明的一点是,在iOS 11中,该库有一个bug修复,所以需要在pod中指定该库的地址,并且指定分支master.

target 'WCDBDemo' do

platform:ios,"8.0"

pod 'WCDB',git: 'https://github.com/Tencent/wcdb.git' , branch: 'master'
pod 'YYModel'

end

将一个已有的OC类进行QRM绑定的过程

  1. 定义该类遵守WCTTableCoding协议,可以在类声明上定义,也可以通过文件模版在category内定义。

这里推荐大家使用第二种,通过文件模板在category内定义,为什么要这样做,就是为了隔离Objective-C++代码

  1. WCDB基于WINQ,引入了Objective-C++代码,所以对于引入了WCDB的源文件,都需要把后缀.m改为.mm,为减少影响范围,可以通过Objective-C的category特性将其隔离,达到只在model层使用Objective-C++编译,而不影响Controller和View。这一点在
    Wiki中是有提到的,

  2. 这样做的好处是不知道大家都有没有理解,这么说,要是你通过第一种方法,不通过category定义,而是选择了在类声明中写,这样的话Message.h 中就需要有宏WCDB_PROPERTY,这样你就在Message.h使用了WCDB的代码,当你把Message.h在其他Controller/View中引用的时候,那相应的Controller/View的.m就需要修改成.mm 。造成不必要的工作,但你用第二种方法写的时候,你就发现在Message.h中是没有任何的关于WCDB的代码的,后面你引用也不需要再去修改!希望大家理解这里

  3. 使用WCDB_PROPERTY宏在头文件声明需要绑定到数据库表的字段(也就是把你的表里面需要的字段在这里用这宏声明一次)

  4. 使用WCDB_IMPLEMENTATIO宏在类文件定义绑定到数据库表的类(把这个类绑定到数据库的表,你会在下面创建数据库的时候创建相应的表,表会和类绑定)

  5. 使用WCDB_SYNTHESIZE宏在类文件定义绑定到数据库表的类(第二步声明了表需要的字段,第三步绑定了表中的类,第四步就等于把表和字段绑定)

创建model

Message.h

@interface Message : NSObject

@property int localID;
@property(retain) NSString *content;
@property(retain) NSDate *createTime;
@property(retain) NSDate *modifiedTime;
@end

Message.mm

@implementation Message
// 利用这个宏定义绑定到表的类
WCDB_IMPLEMENTATION(Message)

// 下面四个宏定义绑定到表中的字段
WCDB_SYNTHESIZE(Message, localID)
WCDB_SYNTHESIZE(Message, content)
WCDB_SYNTHESIZE(Message, createTime)
WCDB_SYNTHESIZE(Message, modifiedTime)

// 约束宏定义数据库的主键
WCDB_PRIMARY(Message, localID)

// 定义数据库的索引属性,它直接定义createTime字段为索引
// 同时 WCDB 会将表名 + "_index" 作为该索引的名称
WCDB_INDEX(Message, "_index", createTime)

@end

Message+WCTTableCoding.h

#import "Message.h"
#import <WCDB/WCDB.h>

@interface Message (WCTTableCoding) <WCTTableCoding>

// 需要绑定到表中的字段在这里声明,在.mm中去绑定
WCDB_PROPERTY(localID)
WCDB_PROPERTY(content)
WCDB_PROPERTY(createTime)
WCDB_PROPERTY(modifiedTime)

@end

创建数据库

 //获取沙盒根目录
    NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    
    // 文件路径
    NSString *filePath = [documentsPath stringByAppendingPathComponent:@"model.sqlite"];
    NSLog(@"path = %@",filePath);
    
    database = [[WCTDatabase alloc]initWithPath:filePath];
    // 数据库加密
    NSData *password = [@"MyPassword" dataUsingEncoding:NSASCIIStringEncoding];
    [database setCipherKey:password];
    //测试数据库是否能够打开
    if ([database canOpen]) {
        
        // WCDB大量使用延迟初始化(Lazy initialization)的方式管理对象,因此SQLite连接会在第一次被访问时被打开。开发者不需要手动打开数据库。
        // 先判断表是不是已经存在
        if ([database isOpened]) {
            
            if ([database isTableExists:tableName]) {
                
                NSLog(@"表已经存在");
                
            }else {
              [database createTableAndIndexesOfName:tableName withClass:Message.class];
        }
    }

插入数据

Message *message = [[Message alloc] init];
message.localID = 1;
message.content = @"Hello, WCDB!";
message.createTime = [NSDate date];
message.modifiedTime = [NSDate date];
/*
 INSERT INTO message(localID, content, createTime, modifiedTime)
 VALUES(1, "Hello, WCDB!", 1496396165, 1496396165);
 */
  [database insertObject:message  into:@"message"];

更新数据

//UPDATE message SET content="Hello, Wechat!";
Message *message = [[Message alloc] init];
message.content = @"Hello, Wechat!";
    
//下面这句在17号的时候和微信团队的人在学习群里面沟通过,这个方法确实是不存在的,使用教程应该会更新,要是没更新注意这个方法
//BOOL result = [database updateTable:@"message" onProperties:Message.content withObject:message];
[database updateAllRowsInTable:@"message" onProperty:Message.content withObject:message];

查询数据

//SELECT * FROM message ORDER BY localID
NSArray<Message *> * message = [database getObjectsOfClass:Message.class fromTable:@"message" orderBy:Message.localID.order()];
NSLog(@">>>> %@",message);

删除数据

[database deleteObjectsFromTable:@"message" where:Message.localID > 0];

WCTDatabase 事务操作,利用WCTTransaction

 BOOL ret = [database beginTransaction];
    ret = [self insertMessage];
    if (ret) {
        
        [database commitTransaction];
        
    }else
        
        [database rollbackTransaction];
    
    return ret;

使用Block处理事务

 BOOL commit  =  [database runTransaction:^BOOL{
      
         BOOL ret = [self insertMessage];
         if (ret) {
             
             return YES;
             
         }else
             return NO;
         
     } event:^(WCTTransactionEvent event) {
         
         NSLog(@"Event %d", event);
     }];
    return commit;

FMDB迁移到WCDB

FMDB迁移到WCDB

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 129,402评论 18 137
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 164,685评论 24 698
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 8,923评论 4 48
  • 主要事件: 了解为何会有蚊子的烦恼 参加家人的乔迁之喜聚餐,马丁老师给我们讲生命密码 活动后交流社区梦想 蚊子烦恼...
    喜觉生活道践行者noya阅读 104评论 0 0
  • 涉及到贵人,很多人都有类似的困惑,感觉欠了太多人情债,怕自己还不起。 其实,不妨加上一个暂时来帮助自己摆脱这方面的...
    成长为价值投资者阅读 64评论 0 0
  • 邀春等春也等你,什么是爱,恰到好处的关心与温暖。手提吉他,别在深冬的眉眼,红尘流年冬终随飘舞的雪花渐离我们的视线,...
    YLJCa阅读 227评论 0 0
  • 1、母亲:因为我要喝母乳。 2、小学阶段:母亲,初中:父亲。小学阶段,妈妈陪我陪得多,每次到了换季的时候总是不停的...
    遇见真实的我阅读 160评论 0 0
  • 从小到大,我都没有怎么感受过家庭的温暖,很小很小的时候父母就离婚了,爸爸又工作忙无暇顾及,我就像物品一样被辗转寄存...
    球球小姐阅读 197评论 0 0