美文网首页
持久化方案-Reaml数据库简介

持久化方案-Reaml数据库简介

作者: 年轻岁月 | 来源:发表于2017-04-23 21:32 被阅读102次
一、Realm官网地址:https://realm.io/cn/
二、Realm框架介绍:
    realm是一个跨平台移动数据库引擎,支持iOS、OS X(Objective-C和Swift)以及Android;
    核心数据引擎C++打造,并不是建立在SQLite之上的ORM, 是拥有独立的数据库存储引擎;
    比sqlite, coredata效率更快、简单易用。
三、Realm辅助工具:
    1、RealmBrowser:可视化访问Realm数据库(AppStore中可下载)
    2、Xcode插件:reaml-cocoa可以快速创建Realm可存储模型对象
      (https://github.com/realm/realm-cocoa)
四、Realm支持的数据类型:
    BOOL, bool, int, NSInteger, long, long long, float, double, NSString, NSDate, NSData, and NSNumber
    注意:不支持集合类型 
    解决方案:序列化成NSData进行存储 或 转换成RLMArray<RLMObject>进行存储(麻烦)
五、Realm数据库:
    1. 用户机制:不同的用户, 使用不同的数据库
      + (void)setDefaultRealmForUser:(NSString *)username {
            RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
            // 使用默认的目录,但是使用用户名来替换默认的文件名
            config.fileURL = [[[config.fileURL URLByDeletingLastPathComponent] URLByAppendingPathComponent:username] URLByAppendingPathExtension:@"realm"];  
            // 将这个配置应用到默认的 Realm 数据库当中
            [RLMRealmConfiguration setDefaultConfiguration:config];
       }

    2. 只读方式打开数据库:config.readOnly = YES;

    3. 数据库文件删除:需要删除数据库文件以及辅助文件(官方要求)
       NSFileManager *manager = [NSFileManager defaultManager];
       RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
       NSArray<NSURL *> *realmFileURLs = @[config.fileURL, 
                                          [config.fileURL URLByAppendingPathExtension:@"lock"], 
                                          [config.fileURL URLByAppendingPathExtension:@"log_a"],
                                          [config.fileURL URLByAppendingPathExtension:@"log_b"],
                                          [config.fileURL URLByAppendingPathExtension:@"note"]
                                          ];
       for (NSURL *URL in realmFileURLs){  
            NSError *error = nil; 
           [manager removeItemAtURL:URL error:&error];
           if(error){//处理错误}
       }
六、Realm增删改查:首先创建数据模型, 必须继承自RLMObject
    6.1 创建对象的方式:1. 普通创建
                     2. 通过父类RLMObject中的方法快速创建:initWithValue(数组或字典)
                        请注意:跟属性顺序需保持一致;
                        所有的必需属性都必须在对象添加到Realm前被赋值;
                        由于Realm在自己的引擎内部有很好的语义解释系统,
                        所以 Objective‑C 的许多属性特性将被忽略,
                        如nonatomic, atomic, strong, copy 和 weak 等,
                        因此为了避免误解,官方推荐在编写数据模型的时候不要使用任何的属性特性。
    6.2 简单的数据操作:
                     1. 保存指定模型:
                        获取RLMRealm对象:RLMRealm *realm = [RLMRealm defaultRealm];
                        方式1:开启写入事务:[realm beginWriteTransaction];
                              添加模型对象:[realm addObject:stu];
                              提交写入事务:[realm commitWriteTransaction];

                        方式2:[realm transactionWithBlock:^{
                                   [realm addObject:stu];
                              }];

                        方式3:[Stu createInRealm:realm withValue:@{@"stu_id": @22, @"name": @"马冬梅2", @"age": @666}];

                     2. 更新指定模型
                        方式1:在事务中直接更新对象
                              [realm beginWriteTransaction];
                              stu.name = @"土豆";
                              [realm commitWriteTransaction];

                        方式2:根据主键进行更新
                              1. 要求操作的模型, 必须实现方法
                                 + (NSString *)primaryKey 返回主键
                              2. 在事务中调用方法:[realm addOrUpdateObject:stu2];

                        方式3:根据主键进行更新
                              1. 要求操作的模型, 必须实现方法
                                 + (NSString *)primaryKey 返回主键
                              2. 在事务中调用方法:
                                 [Stu createOrUpdateInRealm:realm withValue:@{@"stu_id": @22, @"name": @"马冬梅2", @"age": @666}];

                      3. 使用RLMRealm对象, 在事务中删除数据
                        方式1:删除指定的对象,
                              注意: 必须是从realm数据库中获取的模型对象, 而不是自己创建的
                              RLMObject *obj = [realm objectWithClassName:@"Stu" forPrimaryKey:@2];
                              [realm deleteObject:obj];
                     
                        方式2:删除所有对象
                              [realm deleteAllObjects];

                     4. 使用RLMRealm对象, 查询数据
                       注意事项:1. 所有的查询(包括查询和属性访问)在Realm中都是延迟加载的,
                               只有当属性被访问时,才能够读取相应的数据;
                               2. 查询结果并不是数据的拷贝:
                               修改查询结果(在写入事务中)会直接修改硬盘上的数据;
                               3. 一旦检索执行之后, RLMResults将随时保持更新。

                       查询所有:[Stu allObjects]

                       条件查询:RLMResults<Stu *> *stus = [Stu objectsWhere:@"name = '马冬梅'"];

                       排序查询:[stus sortedResultsUsingProperty:@"name" ascending:YES];

                       链式查询:在查询结果的基础上, 进行二次查询
                               [stus objectsWhere:@"address beginswith '北京'"];

                       分页查询:查询出来的结果对象是懒加载, 只有真正访问时, 
                               才会加载相应对象, 所以这里的分页, 其实就是从所有集合中分页获取即可
                               RLMResults<Dog *> *dogs = [Dog allObjects];
                               for (NSInteger i = 0; i < 5; i++) {
                                    Dog *dog = dogs[i];
                                    // …
                               }
七、Realm关系:
    7.1 对一关系:当一个对象持有另外一个对象时, 比如人有一个宠物🐶
    7.2 对多关系:1. 在Dog中, 遵循指定协议方法
                   RLM_ARRAY_TYPE(Dog):
                   RLM_ARRAY_TYPE 宏创建了一个协议,从而允许 RLMArray<Dog> 语法的使用
                2. 在Person中, 定义属性:
                   @property (nonatomic, strong) RLMArray<Dog *><Dog> *dogs;
                   虽然可以给 RLMArray 属性赋值为 nil,
                   但是这仅用于“清空”数组,而不是用以移除数组。
                   这意味着您总是可以向一个 RLMArray 属性中添加对象,
                   即使其被置为了 nil。
                   Person属性意义解释:RLMArray: 属性类型。
                                    <Object *>: 属性的特别化(generic specialization),
                                                这可以阻止在编译时使用错误对象类型的数组。
                                    <Object>: 此RLMArray遵守的协议,
                                                可以让 Realm 知晓如何在运行时确定数据模型的结构。
    7.3 反向关系:人拥有狗, 狗又有相应的主人?
                1. Dog中定义属性:@property (readonly) RLMLinkingObjects *master;
                2. 实现协议方法, 标明链接关系:
                   + (NSDictionary<NSString *,RLMPropertyDescriptor *> *)linkingObjectsProperties {
                         return @{
                                 @"master": [RLMPropertyDescriptor descriptorWithClass:NSClassFromString(@"Stu") propertyName:@"dogs"]
                                 };
                   }
八、可空属性&默认值&忽略属性:
    默认情况下, 属性值可空, 如果强制要求某个属性非空, 可以使用如下方法
    8.1 设置属性不能为nil:+ (NSArray *)requiredProperties;
        特点:如果再次赋值为nil, 则会抛出异常错误
    8.2 设置属性默认值:+ (NSDictionary *)defaultPropertyValues;
    8.3 设置可忽略属性:+ (NSArray *)ignoredProperties;
    开发经验:可以借助忽略属性&只读属性打造计算属性, 完成集合以及UIImage对象的存储与获取
九、Realm数据库通知:
    数据库和结果集都可添加通知;Realm实例将会在每次写入事务提交后,
                           给其他线程上的Realm实例发送通知;必须持有返回的token
    9.1 获取Realm通知:
        self.token = [realm addNotificationBlock:^(NSString *notification, RLMRealm * realm) {
                        // 接收到更改通知, 需要做的事情
                      }];
    9.2 移除通知:[self.token stop];
十、Realm数据库迁移:
    10.1 数据结构的迁移:
         // 在 [AppDelegate didFinishLaunchingWithOptions:] 中进行配置
         RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
         // 设置新的架构版本。
         // 这个版本号必须高于之前所用的版本号
         //(如果您之前从未设置过架构版本,那么这个版本号设置为 0)
         config.schemaVersion = 1;
         // 设置闭包,这个闭包将会在打开低于上面所设置版本号的 Realm 数据库的时候被自动调用
         config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) {
                // 目前我们还未进行数据迁移,因此 oldSchemaVersion == 0
                if (oldSchemaVersion < 1) {
                // 什么都不要做!
                // Realm 会自行检测新增和需要移除的属性,然后自动更新硬盘上的数据库架构
                }
         };
         // 告诉 Realm 为默认的 Realm 数据库使用这个新的配置对象
         [RLMRealmConfiguration setDefaultConfiguration:config];
         // 现在我们已经告诉了 Realm 如何处理架构的变化,打开文件之后将会自动执行迁移
         [RLMRealm defaultRealm];

    10.2 数据的迁移:
         // enumerateObjects:block: 方法遍历了存储在 Realm 文件中的每一个“Person”对象
         [migration enumerateObjects:Person.className block:^(RLMObject *oldObject, RLMObject *newObject) {
               // 将名字进行合并,存放在 fullName 域中
               newObject[@"fullName"] = [NSString stringWithFormat:@"%@ %@",
                                                  oldObject[@"firstName"],
                                                  oldObject[@"lastName"]];
         }];

     10.3 属性重命名:
         [migration renamePropertyForClass:Person.className oldName:@"yearsSinceBirth" newName:@"age"];

     10.4 多版本增量式迁移:根据数据库版本的不同,修改成最新版本(注意不要丢失数据)
          // enumerateObjects:block: 遍历了存储在 Realm 文件中的每一个“Person”对象
          [migration enumerateObjects:Person.className block:^(RLMObject *oldObject, RLMObject *newObject) {
                  // 只有当 Realm 数据库的架构版本为 0 的时候,才添加 “fullName” 属性
                  if (oldSchemaVersion < 1) {
                         newObject[@"fullName"] = [NSString stringWithFormat:@"%@ %@",
                                                            oldObject[@"firstName"],
                                                            oldObject[@"lastName"]];
                  }
          // 只有当 Realm 数据库的架构版本为 0 或者 1 的时候,才添加“email”属性
          if (oldSchemaVersion < 2) {
                newObject[@"email"] = @"";
          }
          }];

相关文章

  • 持久化方案-Reaml数据库简介

    一、Realm官网地址:https://realm.io/cn/ 二、Realm框架介绍: 三、Realm辅助工具...

  • Redis缓存持久化策略

    Redis RDB持久化原理 简介:rdb持久化方案配置讲解,redis的开发者是怎么实现rdb的 rdb持久化配...

  • Win7安装使用redis服务

    Redis简介:1:开源免费,高性能NoSql数据库。2:支持数据持久话。即:RDB快照持久化机制和AOF持久化机...

  • 数据持久化

    iOS中持久化方案有很多,例如:NSUserDefault、KeyChain、File,以及基于数据库的无数子方案...

  • iOS持久化存储方案

    概要 iOS常用的持久化存储方案一般有:NSUserDefault、Keychain,File,数据库等几种方案。...

  • Redis持久化与数据库持久化

    简介 本文简要介绍Redis持久化与数据库持久化的区别,主要参考Redis作者的blog(见下文参考文献);在数据...

  • redis——AOF持久化

    简介 Redis的持久化方式之一RDB是通过保存数据库中的键值对来记录数据库的状态。而另一种持久化方式AOF则是通...

  • redis持久化策略

    一:持久化简介 redis是一种内存数据库,数据保存在内存中,但也可以将数据保存到文件中称之持久化,持久化的目的是...

  • Redis持久化

    Redis持久化 一、持久化简介 因为Redis是内存数据库,它将自己的数据库状态储存在内存里面,所以如果不想办法...

  • redis持久化方案

    前言 redis提供两种持久化方案: RDB持久化(原理是将Reids在内存中的数据库记录定时dump到磁盘上的R...

网友评论

      本文标题:持久化方案-Reaml数据库简介

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