iOS开发通过微信学习WCDB(二)

108 篇文章 1 订阅
3 篇文章 0 订阅

  通过《iOS开发通过微信学习WCDB(一)》这篇博客,相信大家对WCDB已经有了一个简单的了解和认识。这篇文章主要是为了进一步深入的学习
###数据库加密
  上篇文章中提到了,自己在刚开始使用的时候没有效果,后来通过和WCDB的作者联系,了解到内容如下:WCDB如果要使用加密功能,必须在创建数据库后,没有存储数据之前,代码如下:

- (void)encryptDBData{
    NSData *password = [@"MyPassword" dataUsingEncoding:NSASCIIStringEncoding];
    [self.database setCipherKey:password];
}

执行完配置CipherKey的操作之后,然后再往数据库中插入数据,这个时候数据就被加密了。而如果之前没有使用加密功能的话,如果想要使用加密功能的话,需要把数据从原来的数据库中读取出来,然后新建一个数据库,然后配置CipherKey,将老数据库中的数据插入新数据即可。另外由于WCDB使用了配置CipherKey的概念,只要配置了CipherKey,WCDB内部自动实现了加密解密的功能。
###删除数据库中的表

- (void)deleteTable{
    [self.database dropTableOfName:@"message"];//其中message为表的名字,删除表后,message表中存储的数据也一块被删除掉了。
}

###数据库中添加列

- (void)addTableColumn{
    [self.database addColumn:Message.age.def(WCTColumnTypeInteger64) forTable:@"message"];
    
}

注:以上面的代码为例,添加列的时候,需要在Message.h中把属性加上,代码如下:

@property(nonatomic, assign) NSInteger age;

Message.mm中把下面的代码添加上:

WCDB_SYNTHESIZE(Message, age)

Message+WCTTableCoding.h中需要实现如下代码:

WCDB_PROPERTY(age)

###根据指定条件创建表
  在实际的开发过程中,我们有的时候对于数据模型的property,并不是每一个都要保存到数据库中的,对于这种情况,我们直接使用《iOS开发通过微信学习WCDB(一)》中创建表的操作就不会太合适了,针对这种情况,我们可以选择自定义一些条件来创建表,具体代码如下:

 [self.database createTableOfName:@"TestModel" withColumnDefList:{TestModel.modelID.def(WCTColumnTypeInteger64)}];//这里可以添加多列
    NSString *indexSubfix = @"_index";
    NSString *indexName = [@"TestModel" stringByAppendingString:indexSubfix];
    [self.database createIndexOfName:@"TestModel_index" withIndexList:{TestModel.modelID.index()} forTable:@"TestModel"];//这里用来设置index字端。

###数据库的恢复
  WCDB提供了数据库的恢复功能,在数据库损坏的时候能够过进行修复,这个功能非常的棒,我这边进行了尝试,发现效果还是不错的,但是也有一些坑点。这里就给大家说一下。
####坑点一,数据库创建时数据库的名字不能有sqlite的后缀名
  刚开始自己创建数据库的时候数据库的名字是testDB.sqlite带有sqlite的后缀名,在执行,增、删、查、改的操作都没有问题, 但是在执行恢复操作的时候却没有恢复成功。
####坑点二,数据库创建后需要执行备份的操作
  数据库创建后需要执行备份的操作,具体如下:

    NSData *backupCipher = [@"backupCipher" dataUsingEncoding:NSASCIIStringEncoding];
    [self.database backupWithCipher:backupCipher];

  坑点说完了,下面大家可以看一下数据库恢复的代码:

- (void)repairDataBase{
    NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];//目标数据库的路径
    NSString *path = [NSString stringWithFormat:@"%@/testDB",docDir];
    [self.database close:^{//模拟数据库损坏的操作
        FILE *file = fopen(path.UTF8String, "rb+");
        unsigned char *zeroPage = new unsigned char[100];
        memset(zeroPage, 0, 100);
        fwrite(zeroPage, 100, 1, file);
        fclose(file);
    }];

    NSLog(@"The count of objects corrupted: %lu", [self.database getAllObjectsOfClass:Message.class fromTable:@"message"].count);
    
    NSData *password = [@"MyPassword" dataUsingEncoding:NSASCIIStringEncoding];
    NSData *backupCipher = [@"backupCipher" dataUsingEncoding:NSASCIIStringEncoding];

    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];

        NSString *recoverPath = [NSString stringWithFormat:@"%@/recoverDB",docDir];//临时恢复的数据库的路径
        WCTDatabase * recover = [[WCTDatabase alloc] initWithPath:recoverPath];
        NSData * password = [ @"MyPassword"  dataUsingEncoding:NSASCIIStringEncoding];
        NSData * backupPassword = [ @"MyBackupPassword"  dataUsingEncoding:NSASCIIStringEncoding];
        int pageSize = 4096 ; // iOS上的默认值为4096,macOS上的默认值为1024。
        [self.database close:^ {
           BOOL status = [recover recoverFromPath:path
                        withPageSize:pageSize
                        backupCipher:backupCipher
                      databaseCipher:password];
            
            NSLog(@"The count of objects reCovered: %lu", [recover getAllObjectsOfClass:Message.class fromTable:@"message"].count);

        }];
    });
     
}

###数据库中的事务
  在数据库中,事务可以说是高级玩法啊,能够帮助我们解决复杂的数据库操作处理。关于事务的详细解释可以参考百度百科。在实际的工作过程中,我们会遇到某个操作依赖于对数据库的复合处理,等处理所有的数据都数据成功后,才可以执行我们接下来的操作,否则就回滚。这种情况下事务就派上用场了。我写了一个简单的代码如下:

BOOL status = [self.database beginTransaction];
    Message *message = [[Message alloc] init];
    message.localID = 10000;
    message.content = @"Hello, Jack!!!";
    message.createTime = [NSDate date];
    message.modifiedTime = [NSDate date];
    
    
   BOOL ret = [self.database insertObject:message
                            into:@"message"];
    if (ret) {
        ret = [self.database commitTransaction];//只有commit过了,对数据库的操作才会真正生效。
    } else {
        ret = [self.database rollbackTransaction];
    }
}

另外WCDB提供了一个批量插入数据的一个方法,里面用到了内置的事物,具体代码如下:

NSMutableArray *messages = [NSMutableArray new];
    for (int i = 0; i<100; i++) {
        Message *message = [[Message alloc] init];
        message.localID = i;
        message.content = @"Hello, Jack!!!";
        message.createTime = [NSDate date];
        message.modifiedTime = [NSDate date];
        [messages addObject:message];
    }
    [self.database insertObjects:messages into:@"message"];

更多优质文章,可以微信扫码关注:
这里写图片描述

wcdb官方文档

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值