上海恩美路演数据库操作Objective-C

WCDB for iOS/macOS

2017-09-14  本文已影响4508人  AKyS佐毅
屏幕快照 2017-09-14 下午4.27.49.png

基本特性

[database getObjectsOfClass:WCTSampleConvenient.class
                  fromTable:tableName
                      where:WCTSampleConvenient.intValue>=10
                      limit:20];

批量写操作性能测试:

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

通过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

上一篇下一篇

猜你喜欢

热点阅读