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

  通过之前的两篇文章对wcdb能够简单的使用了,这些知识储备多时,最近终于可以派上用场了,最近app有一个通讯录的新功能,实现联系人列表的排序,以及检索,刚好可以用用wcdb去实现。

联系人模型的建立

  我首先建立了联系人的模型,具体代码如下:

@interface YWContactModel : NSObject

@property (nonatomic,assign) NSInteger uid;             ///< 用户id
@property (nonatomic,copy) NSString *nickname;          ///< 用户昵称
@property (nonatomic,copy) NSString *avatar;            ///< 用户头像
@property (nonatomic,copy) NSString *pinyin;            ///< 昵称的拼音
@property (nonatomic,assign) NSInteger ownerCount;      ///< 拥有者数量

@end

由于考虑到可能有多个用户在同一个手机上使用的可能,我这边新建了一个表,联系人关系表。具体代码如下:

@interface YWContactRelationModel : NSObject

@property(nonatomic, assign) NSInteger ownerUid;  ///< 用户的uid
@property(nonatomic, assign) NSInteger uid;       ///< 通讯录中朋友的uid

@end

大家可能已经注意到了,ownerCount这个字段,由于一个用户可能有多个朋友,那么他可能是好多人通讯录列表中的联系人,这个 字段主要是为了方便对本地保存的联系人删除管理。
另外由于要用到多表查询,因此需要用到联合主键。这里我在YWContactRelationModel.mm文件中实现如下:

@implementation YWContactRelationModel

+ (nullable NSDictionary<NSString *, id> *)modelCustomPropertyMapper{
    return @{@"uid":@"id"};
}

- (NSInteger)ownerUid{
    if (!_ownerUid) {
        _ownerUid = [YWAccountManager sharedManager].account.user.uid;
    }
    
    return _ownerUid;
}
WCDB_IMPLEMENTATION(YWContactRelationModel)
WCDB_SYNTHESIZE(YWContactRelationModel, ownerUid)
WCDB_SYNTHESIZE(YWContactRelationModel, uid)

WCDB_MULTI_PRIMARY_ASC(YWContactRelationModel, "relation", ownerUid)//设置联合主键
WCDB_MULTI_PRIMARY(YWContactRelationModel, "relation", uid)//设置联合主键

@end

进行多表联合查询

  一切准备就绪,开始进行多表联合查询,我的目标就是查询后,只需要简单的遍历就能够实现联系人按照拼音首字母进行分类,重点是:遍历循环要尽可能的少 。我最初的方案如下:
对字母数组进行便利,根据索引进行数据库查询,然后执行的分类操作,但是运行后并没有出现sql语句的错误,结果却为空和开源库作者沟通,目前尚未有结果

//NSArray *indexArray = @[@"A",@"B",@"C",@"D",@"E",@"F",@"G",@"H",@"I",@"J",@"K",@"L",@"M",@"N",@"O",@"P",@"Q",@"R",@"S",@"T",@"U",@"V",@"W",@"X",@"Y",@"Z",@"#"];

WCTMultiSelect *multiSelect = [[YWWCDBHelper shareInstance].database prepareSelectMultiObjectsOnResults:YWContactModel.AllProperties.inTable(@"contact") fromTables:@[@"contact",@"contactRelation"]];
        [multiSelect where:YWContactRelationModel.ownerUid.inTable(@"contactRelation") == uid && YWContactRelationModel.uid.inTable(@"contactRelation") == YWContactModel.uid.inTable(@"contact") && YWContactModel.pinyin.inTable(@"contact").upper().substr(0, 1) == index];
        NSArray *resultArray = [multiSelect allMultiObjects];

项目不等人,我又想了一个折中的方案就是,让查询结果按照拼音字段进行分类,然后查询,从index='A’开始便利,如果联系人contact的拼音首字母和A相同,那么就进行失去操作添加拾取操作,如果不相同,就切换index为当前contact的拼音首字母。这样只需要一遍的循环遍历就可以实现联系人按照拼音字母进行分类。
修改后的方案如下:


NSMutableArray *datas = [NSMutableArray new];
    NSMutableArray *sectionIndexArray = [NSMutableArray new];
    WCTMultiSelect *multiSelect = [[YWWCDBHelper shareInstance].database prepareSelectMultiObjectsOnResults:YWContactModel.AllProperties.inTable(@"contact") fromTables:@[@"contact",@"contactRelation"]];
    [multiSelect where:YWContactRelationModel.ownerUid.inTable(@"contactRelation") == uid && YWContactRelationModel.uid.inTable(@"contactRelation") == YWContactModel.uid.inTable(@"contact")];
    [multiSelect groupBy:{YWContactModel.pinyin.inTable(@"contact")}];
    NSArray *resultArray = [multiSelect allMultiObjects];
    NSMutableArray *contacts = [NSMutableArray new];
    NSString *index = @"A";
    for (NSDictionary *dic in resultArray) {
        YWContactModel *contact = (YWContactModel *)[dic objectForKey:@"contact"];
        if ([contact.pinyin.uppercaseString hasPrefix:index]) {
            [contacts addObject:contact];
            if (![sectionIndexArray containsObject:index]) {
                [sectionIndexArray addObject:index];
            }
        }else{
            index = [contact.pinyin substringWithRange:NSMakeRange(0, 1)];
            [contacts addObject:contact];
            [sectionIndexArray addObject:index];
            [datas addObject:contacts];
            contacts = [NSMutableArray new];
        }
    }

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

猜你喜欢

转载自blog.csdn.net/HHL110120/article/details/87966743