持久化方案-Reaml數(shù)據(jù)庫簡介

一住拭、Realm官網(wǎng)地址:https://realm.io/cn/
二挪略、Realm框架介紹:
    realm是一個跨平臺移動數(shù)據(jù)庫引擎,支持iOS滔岳、OS X(Objective-C和Swift)以及Android杠娱;
    核心數(shù)據(jù)引擎C++打造,并不是建立在SQLite之上的ORM, 是擁有獨立的數(shù)據(jù)庫存儲引擎谱煤;
    比sqlite, coredata效率更快摊求、簡單易用。
三刘离、Realm輔助工具:
    1室叉、RealmBrowser:可視化訪問Realm數(shù)據(jù)庫(AppStore中可下載)
    2睹栖、Xcode插件:reaml-cocoa可以快速創(chuàng)建Realm可存儲模型對象
      (https://github.com/realm/realm-cocoa)
四、Realm支持的數(shù)據(jù)類型:
    BOOL, bool, int, NSInteger, long, long long, float, double, NSString, NSDate, NSData, and NSNumber
    注意:不支持集合類型 
    解決方案:序列化成NSData進行存儲 或 轉換成RLMArray<RLMObject>進行存儲(麻煩)
五茧痕、Realm數(shù)據(jù)庫:
    1. 用戶機制:不同的用戶, 使用不同的數(shù)據(jù)庫
      + (void)setDefaultRealmForUser:(NSString *)username {
            RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
            // 使用默認的目錄野来,但是使用用戶名來替換默認的文件名
            config.fileURL = [[[config.fileURL URLByDeletingLastPathComponent] URLByAppendingPathComponent:username] URLByAppendingPathExtension:@"realm"];  
            // 將這個配置應用到默認的 Realm 數(shù)據(jù)庫當中
            [RLMRealmConfiguration setDefaultConfiguration:config];
       }

    2. 只讀方式打開數(shù)據(jù)庫:config.readOnly = YES;

    3. 數(shù)據(jù)庫文件刪除:需要刪除數(shù)據(jù)庫文件以及輔助文件(官方要求)
       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增刪改查:首先創(chuàng)建數(shù)據(jù)模型, 必須繼承自RLMObject
    6.1 創(chuàng)建對象的方式:1. 普通創(chuàng)建
                     2. 通過父類RLMObject中的方法快速創(chuàng)建:initWithValue(數(shù)組或字典)
                        請注意:跟屬性順序需保持一致曼氛;
                        所有的必需屬性都必須在對象添加到Realm前被賦值;
                        由于Realm在自己的引擎內(nèi)部有很好的語義解釋系統(tǒng)令野,
                        所以 Objective?C 的許多屬性特性將被忽略搪锣,
                        如nonatomic, atomic, strong, copy 和 weak 等,
                        因此為了避免誤解彩掐,官方推薦在編寫數(shù)據(jù)模型的時候不要使用任何的屬性特性构舟。
    6.2 簡單的數(shù)據(jù)操作:
                     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:根據(jù)主鍵進行更新
                              1. 要求操作的模型, 必須實現(xiàn)方法
                                 + (NSString *)primaryKey 返回主鍵
                              2. 在事務中調(diào)用方法:[realm addOrUpdateObject:stu2];

                        方式3:根據(jù)主鍵進行更新
                              1. 要求操作的模型, 必須實現(xiàn)方法
                                 + (NSString *)primaryKey 返回主鍵
                              2. 在事務中調(diào)用方法:
                                 [Stu createOrUpdateInRealm:realm withValue:@{@"stu_id": @22, @"name": @"馬冬梅2", @"age": @666}];

                      3. 使用RLMRealm對象, 在事務中刪除數(shù)據(jù)
                        方式1:刪除指定的對象,
                              注意: 必須是從realm數(shù)據(jù)庫中獲取的模型對象, 而不是自己創(chuàng)建的
                              RLMObject *obj = [realm objectWithClassName:@"Stu" forPrimaryKey:@2];
                              [realm deleteObject:obj];
                     
                        方式2:刪除所有對象
                              [realm deleteAllObjects];

                     4. 使用RLMRealm對象, 查詢數(shù)據(jù)
                       注意事項:1. 所有的查詢(包括查詢和屬性訪問)在Realm中都是延遲加載的堵幽,
                               只有當屬性被訪問時狗超,才能夠讀取相應的數(shù)據(jù);
                               2. 查詢結果并不是數(shù)據(jù)的拷貝:
                               修改查詢結果(在寫入事務中)會直接修改硬盤上的數(shù)據(jù);
                               3. 一旦檢索執(zhí)行之后, 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中, 遵循指定協(xié)議方法
                   RLM_ARRAY_TYPE(Dog):
                   RLM_ARRAY_TYPE 宏創(chuàng)建了一個協(xié)議努咐,從而允許 RLMArray<Dog> 語法的使用
                2. 在Person中, 定義屬性:
                   @property (nonatomic, strong) RLMArray<Dog *><Dog> *dogs;
                   雖然可以給 RLMArray 屬性賦值為 nil,
                   但是這僅用于“清空”數(shù)組殴胧,而不是用以移除數(shù)組渗稍。
                   這意味著您總是可以向一個 RLMArray 屬性中添加對象,
                   即使其被置為了 nil团滥。
                   Person屬性意義解釋:RLMArray: 屬性類型竿屹。
                                    <Object *>: 屬性的特別化(generic specialization),
                                                這可以阻止在編譯時使用錯誤對象類型的數(shù)組灸姊。
                                    <Object>: 此RLMArray遵守的協(xié)議拱燃,
                                                可以讓 Realm 知曉如何在運行時確定數(shù)據(jù)模型的結構。
    7.3 反向關系:人擁有狗, 狗又有相應的主人?
                1. Dog中定義屬性:@property (readonly) RLMLinkingObjects *master;
                2. 實現(xiàn)協(xié)議方法, 標明鏈接關系:
                   + (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父晶;
    開發(fā)經(jīng)驗:可以借助忽略屬性&只讀屬性打造計算屬性, 完成集合以及UIImage對象的存儲與獲取
九哮缺、Realm數(shù)據(jù)庫通知:
    數(shù)據(jù)庫和結果集都可添加通知;Realm實例將會在每次寫入事務提交后甲喝,
                           給其他線程上的Realm實例發(fā)送通知尝苇;必須持有返回的token
    9.1 獲取Realm通知:
        self.token = [realm addNotificationBlock:^(NSString *notification, RLMRealm * realm) {
                        // 接收到更改通知, 需要做的事情
                      }];
    9.2 移除通知:[self.token stop];
十、Realm數(shù)據(jù)庫遷移:
    10.1 數(shù)據(jù)結構的遷移:
         // 在 [AppDelegate didFinishLaunchingWithOptions:] 中進行配置
         RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
         // 設置新的架構版本。
         // 這個版本號必須高于之前所用的版本號
         //(如果您之前從未設置過架構版本茎匠,那么這個版本號設置為 0)
         config.schemaVersion = 1;
         // 設置閉包格仲,這個閉包將會在打開低于上面所設置版本號的 Realm 數(shù)據(jù)庫的時候被自動調(diào)用
         config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) {
                // 目前我們還未進行數(shù)據(jù)遷移,因此 oldSchemaVersion == 0
                if (oldSchemaVersion < 1) {
                // 什么都不要做诵冒!
                // Realm 會自行檢測新增和需要移除的屬性凯肋,然后自動更新硬盤上的數(shù)據(jù)庫架構
                }
         };
         // 告訴 Realm 為默認的 Realm 數(shù)據(jù)庫使用這個新的配置對象
         [RLMRealmConfiguration setDefaultConfiguration:config];
         // 現(xiàn)在我們已經(jīng)告訴了 Realm 如何處理架構的變化,打開文件之后將會自動執(zhí)行遷移
         [RLMRealm defaultRealm];

    10.2 數(shù)據(jù)的遷移:
         // 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 多版本增量式遷移:根據(jù)數(shù)據(jù)庫版本的不同侮东,修改成最新版本(注意不要丟失數(shù)據(jù))
          // enumerateObjects:block: 遍歷了存儲在 Realm 文件中的每一個“Person”對象
          [migration enumerateObjects:Person.className block:^(RLMObject *oldObject, RLMObject *newObject) {
                  // 只有當 Realm 數(shù)據(jù)庫的架構版本為 0 的時候,才添加 “fullName” 屬性
                  if (oldSchemaVersion < 1) {
                         newObject[@"fullName"] = [NSString stringWithFormat:@"%@ %@",
                                                            oldObject[@"firstName"],
                                                            oldObject[@"lastName"]];
                  }
          // 只有當 Realm 數(shù)據(jù)庫的架構版本為 0 或者 1 的時候豹芯,才添加“email”屬性
          if (oldSchemaVersion < 2) {
                newObject[@"email"] = @"";
          }
          }];
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末悄雅,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子铁蹈,更是在濱河造成了極大的恐慌宽闲,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件握牧,死亡現(xiàn)場離奇詭異容诬,居然都是意外死亡,警方通過查閱死者的電腦和手機沿腰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門览徒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人颂龙,你說我怎么就攤上這事习蓬。” “怎么了措嵌?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵躲叼,是天一觀的道長。 經(jīng)常有香客問我铅匹,道長押赊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任包斑,我火速辦了婚禮,結果婚禮上涕俗,老公的妹妹穿的比我還像新娘罗丰。我一直安慰自己,他們只是感情好再姑,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布萌抵。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绍填。 梳的紋絲不亂的頭發(fā)上霎桅,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機與錄音讨永,去河邊找鬼滔驶。 笑死,一個胖子當著我的面吹牛卿闹,可吹牛的內(nèi)容都是我干的揭糕。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼锻霎,長吁一口氣:“原來是場噩夢啊……” “哼著角!你這毒婦竟也來了?” 一聲冷哼從身側響起旋恼,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤吏口,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后冰更,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體产徊,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年冬殃,在試婚紗的時候發(fā)現(xiàn)自己被綠了囚痴。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡审葬,死狀恐怖深滚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情涣觉,我是刑警寧澤痴荐,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站官册,受9級特大地震影響生兆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜膝宁,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一鸦难、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧员淫,春花似錦合蔽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沃斤。三九已至,卻和暖如春刃宵,著一層夾襖步出監(jiān)牢的瞬間衡瓶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工牲证, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留哮针,地道東北人。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓从隆,卻偏偏與公主長得像诚撵,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子键闺,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容