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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,099评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,563评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,611评论 4 59
  • 主要事件: 了解为何会有蚊子的烦恼 参加家人的乔迁之喜聚餐,马丁老师给我们讲生命密码 活动后交流社区梦想 蚊子烦恼...
    喜觉生活道践行者noya阅读 329评论 0 0
  • 涉及到贵人,很多人都有类似的困惑,感觉欠了太多人情债,怕自己还不起。 其实,不妨加上一个暂时来帮助自己摆脱这方面的...
    成长为价值投资者阅读 121评论 0 0