美文网首页
Realm数据库使用

Realm数据库使用

作者: Vijay_ | 来源:发表于2017-11-05 14:41 被阅读22次
    • 注意@property RLMArray<YPCar> *oldcars;定义属性时 这里不是泛型 而是协议!!!
    • 所有字段前建议不要加引用修饰符
    • RLMArray<$RLMObject>类型属性不要初始化,该属性是懒加载的 会自动初始化,直接使用就可以
      官方文档
      官方文档地址

    修改表结构(数据库模型)

    //    先拿到当前的配置对象
        RLMRealmConfiguration* config = [RLMRealmConfiguration defaultConfiguration];
    //    设置配置对象的版本号为一个新的版本号
        config.schemaVersion  = 4;
    //    设置迁移block
        config.migrationBlock = ^(RLMMigration * _Nonnull migration, uint64_t oldSchemaVersion) {
            NSLog(@"%llu",oldSchemaVersion);
    //    遍历当前版本的VJRealmModel模型
            [migration enumerateObjects:VJRealmModel.className block:^(RLMObject * _Nullable oldObject, RLMObject * _Nullable newObject) {
    //            如果当前版本号小于设置的新版本号则为上一个版本号
                if (oldSchemaVersion<4) {
    //                即修改id字段为一个字符串类型
                    newObject[@"id"] = @"";
    //                !! newObject[$property]如果字段原来没有则新增 如果原来有则替换
    //                !! 需要设置该字段为什么类型给它赋什么类型的值就可以
                    newObject[@"name"] = @"";
                };
            }];
        };
    //    !! 注意 设置完后要记得把设置好的配置对象替换给当前进程配置对象
        [RLMRealmConfiguration setDefaultConfiguration:config];
    //    !! 只有开启realm操作时才会调用上面配置对象中设置的迁移block
        RLMRealm* realm = [RLMRealm defaultRealm];
        VJRealmModel* model = [[VJRealmModel alloc] init];
        model.id = [[NSUUID UUID]UUIDString]  ;
        model.name = @"hello";
        [realm beginWriteTransaction];
        [realm deleteAllObjects];
        [realm addObject:model];
        [realm commitWriteTransaction];
    
    

    创建数据

    - (void)createDataBase:(NSString*)dataBaseName{
    //  在用户域中找到文件documents目录
        NSArray* arr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString* path = [arr firstObject];
    //    在用户documents目录字符串后面添加/$dataBaseName.realm
    //    例:/Users/jiewang/3E3E4E24-849E-4476-B776-E809C102355C/Documents/vijayData
        NSString* filePath = [path stringByAppendingPathComponent:[dataBaseName stringByAppendingString:@".realm"]];
        YPLog(@"%@",filePath);
        
        RLMRealmConfiguration* config = [RLMRealmConfiguration defaultConfiguration];
        config.readOnly = NO;
        NSInteger currentSchemaVersion = 1.0;
        config.schemaVersion = currentSchemaVersion;
        config.fileURL = [NSURL URLWithString:filePath];
        config.migrationBlock = ^(RLMMigration * _Nonnull migration, uint64_t oldSchemaVersion) {
            if (oldSchemaVersion < currentSchemaVersion) {
    //            数据迁移block
            }
        };
        [RLMRealmConfiguration setDefaultConfiguration:config];
        YPLog(@"%@" ,[RLMRealmConfiguration defaultConfiguration].fileURL);
    }
    

    关于RLMObject的关系

    • 一对多关系
    # Realm数据库不支持NSArray所以需要用宏来声明一个RLMArray类型
    //声明一个RLMArray属性
    @property RLMArray<VJCar> *cars;
    //对应的类需要声明RLMArray类型
    RLM_ARRAY_TYPE(VJCar) // 定义RLMArray<VJCar>
    
    • 一对一关系
    //可以直接引用指定的类作为属性 只要继承了RMLObject类的类都可以作为一对一关系
    @property VJRealmModel* owner;
    
    • 多对多
    # RLM数据库链性是单向的,所以不是真的双向引用只是互相单向引用了
    # 由于两个类都要互相引用当互相引用.h文件时会报错
    #import <Realm/Realm.h>
    RLM_ARRAY_TYPE(VJCar) // 定义RLMArray<VJCar>
    RLM_ARRAY_TYPE(VJRealmModel) // 定义RLMArray<RLMUser>
    @interface VJRealmModel : RLMObject
    @property NSString* id;
    @property NSString* name;
    @property RLMArray<VJCar> *cars;
    @end
    
    @interface VJCar : RLMObject
    @property NSString* carName;
    @property NSString* id;
    @property VJRealmModel* owner;
    @property RLMArray<VJRealmModel>* peoples;
    //所以需要写在一个.h文件中
    
    • 属性设置
    #import "VJRealmModel.h"
    
    @implementation VJRealmModel
    //主键
    + (NSString *)primaryKey{
        return @"id";
    }
    //忽略的属性
    + (NSArray<NSString *> *)ignoredProperties{
        return @[@"hey"];
    }
    //索引
    + (NSArray<NSString *> *)indexedProperties{
       return  @[@"id"];
    }
    //非空属性
    + (NSArray<NSString *> *)requiredProperties{
        return @[@"cars"];
    }
    //属性默认值设置
    + (NSDictionary *)defaultPropertyValues{
        return @{@"oops":@"oops"};
    }
    @end
    

    关于线程

    #1.官方给出了一个建议:
    
    //由于 Realm 采用了 MVCC 设计架构,
    //读取操作并不会因为写入事务正在进行而受到影响。
    //除非您需要立即使用多个线程来同时执行写入操作,
    //不然您应当采用批量化的写入事务,而不是采用多次少量的写#入事务。
    [realm transactionWithBlock:^{
                [realm addObject: Car];
    }];
    
    #2.[RLMRealm defaultRealm]是获取当前线程的realm数据库上下文 
    #所以当在不同线程时需要获取不同的上下文对象 不能跨线程访问
    
    

    增删改查函数

    RLMRealm* realm = [RLMRealm defaultRealm];
    [realm transactionWithBlock:^{
    //增
    [realm addObject:$RLMObject];
    [realm addObjects:@[$RLMObject]];
    //删
    [realm deleteAllObjects]; //删除数据库所有对象
    [realm deleteObject:$RLMObject];
    [realm deleteObjects:@[$RLMObject]];
    //改
    [[model.cars objectAtIndex:0] setCarName:@"火车"];
    [realm addOrUpdateObject:model];//如果该对象已存在则修改 不存在则为添加
    [realm addOrUpdateObjects:@[$RLMObject]];//批量
    //查
    #注:RLMResult需要设置泛型 不然不能调用返回的对象的方法
    #RLMResult<$泛型*>* result
    #查询是懒加载 只有使用对象时才会执行查询 查询出来的对象如果在事务中进行了修改 当事务提交时会修改数据库 类似hibernate
    #不能跨线程访问realm
    
    //使用NSPredicate查询
    NSPredicate* pred = [NSPredicate predicateWithFormat:@"carName = %@ AND id = %@",@"火车",@"E295BECA-AE78-4A67-8946-B47C760B69DE"];
    RLMResults<VJCar*>* results = [VJCars objectsWithPredicate:pred];
    NSLog(@"%@",[results objectAtIndex:0]);
    }]
    //使用断言查询 注意参数需要用单引号
    RLMResults<VJCar*>* results = [VJCar objectsWhere:@"carName = '火车'"];
    //查询所有数据
    RLMResults<VJCar*>* results= [VJCar allObjects];
    //排序查询
    RLMResults<VJRealmModel*>* results = 
    [[VJRealmModel objectsWhere:@"oops = 'oops'"] 
    sortedResultsUsingKeyPath:@"$property" ascending:$YES升序NO降序];
    

    相关文章

      网友评论

          本文标题:Realm数据库使用

          本文链接:https://www.haomeiwen.com/subject/vzncmxtx.html