Realm -- oc版使用(上)

Realm 移動端數(shù)據(jù)庫

  • 首先簡單介紹一下Realm
    移動端跨平臺數(shù)據(jù)庫,相較于CoreData、FMDB等數(shù)據(jù)持久化方案,Realm的使用更加方便,且上手更快,可利用Realm Browser軟件查看,底層不同于SQLite,是基于C++開發(fā)的存儲引擎。(官方文檔可以更好的了解)
    1.Realm是一個類MVCC(多版本并發(fā)控制技術)數(shù)據(jù)庫,每個連接的線程在特定的時刻都有一個數(shù)據(jù)庫的快照。MVCC在設計上采用了和Git一樣的源文件管理算法,也就是說你的每個連接線程就好比在一個分支(也就是數(shù)據(jù)庫的快照)上工作,但是你并沒有得到一個完整的數(shù)據(jù)庫拷貝。Realm和一些真正的MVCC數(shù)據(jù)庫如MySQL是不同的,Realm在某個時刻只能有一個寫操作,且總是操作最新的數(shù)據(jù)版本,不能在老版本操作。
    2.Realm的底層是用B+樹實現(xiàn),很多的文件系統(tǒng)都在使用它做元數(shù)據(jù)索引,n叉樹,n棵子樹的結點中含有n個關鍵字,每個關鍵字不保存數(shù)據(jù),只用來索引,所有數(shù)據(jù)都保存在葉子節(jié)點。
    所以,Realm使每一個連接的線程都會有數(shù)據(jù)在一個特定時刻的快照,同時寫入過程也不用加鎖,也就解決了數(shù)據(jù)庫的并發(fā)問題。
    3.Realm 是 SQLite 和 Core Data 的替代者,得益于其零拷貝的設計,幾乎沒有內(nèi)存開銷,因為每一個 Realm 對象直接通過一個本地 long 指針和底層數(shù)據(jù)庫對應,這個指針是數(shù)據(jù)庫中數(shù)據(jù)的鉤子。通常的數(shù)據(jù)庫中,我們查詢請求會轉(zhuǎn)化為一系列的sql語句,創(chuàng)建一個數(shù)據(jù)庫連接,再通過內(nèi)部的查詢優(yōu)化完成對應的查詢工作,讀取磁盤上的數(shù)據(jù)庫文件,返回這些內(nèi)容并存儲在內(nèi)存中,最后轉(zhuǎn)換為我們可使用的格式或者類型。
    4.對于零拷貝設計,主要是數(shù)據(jù)庫文件通過Memory-mapped, Memory – mapped I/O 就是把磁盤上的file 映射到內(nèi)存中,當我們從內(nèi)存上獲取相應字節(jié)時,對應的file就會被讀取,同樣,我們在內(nèi)存上存儲字節(jié)時,對應的file就會被寫入,我們也就不需要通過read,write系統(tǒng)調(diào)用去操作I/O。Realm 允許文件在沒有做反序列化的情況下直接從內(nèi)存讀取,這樣大大提高了讀取效率。

對Realm架構更多感興趣的可參閱以上文章,本文不做贅述。
Realm數(shù)據(jù)庫 從入門到“放棄”
iOS學習筆記(11)-Realm初探
很感謝以上兩篇文章的作者,對當時初識realm的我?guī)椭艽蟆?/p>

Realm的安裝

  • 推選cocoapods 簡單方便,便于管理
    在項目的Podfile中,添加pod 'Realm',在終端運行pod install。
    目前使用2.9.1版本 最新3.0.0測試版

Realm基礎使用

對于數(shù)據(jù)庫,首先就是建庫,建表。對比SQLite,通過一系列SQL語句完成,我們來看看realm中如何操作。

  • 建庫
    默認數(shù)據(jù)庫
    通過調(diào)用 [RLMRealm defaultRealm] 來初始化以及訪問 realm變量。
    存在于Documents (iOS) 或者 Application Support (OS X)文件夾下的一個名為“default.realm”的文件
    數(shù)據(jù)庫配置
    通過 RLMRealmConfiguration 來處理
+ (void)setDefaultRealmForUser:(NSString *)username {
  RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];

  // 使用默認的目錄,但是使用用戶名來替換默認的文件名
  config.fileURL = [[[config.fileURL URLByDeletingLastPathComponent]
                      URLByAppendingPathComponent:username]
                      URLByAppendingPathExtension:@"realm"];

  // 將這個配置應用到默認的 Realm 數(shù)據(jù)庫當中
  [RLMRealmConfiguration setDefaultConfiguration:config];
}
  • 建表
    對于Realm而言,建表其實就是創(chuàng)建模型類,通過繼承 RLMObject 或者一個已經(jīng)存在的模型類,您就可以創(chuàng)建一個新的 Realm 數(shù)據(jù)模型對象。Realm模型對象在形式上基本上與其他 Objective?C 對象相同。
image.png

存儲字段對應類屬性

支持的數(shù)據(jù)類型有BOOL、bool、int、NSInteger、long、long long、float、double、NSString、NSDate、NSData 以及 被特殊類型標記的 NSNumber,注意:Realm不支持auto_increment類型
m文件中可設置可空屬性(Optional Properties),屬性特性(attributes),索引屬性(Indexed Properties),屬性默認值,對象的自更新特性,忽略屬性。詳細可見官方文檔
此處僅介紹下主鍵(Primary Keys)
重寫 [+primaryKey] 屬性id 作為主鍵

+ (NSString *)primaryKey {
    return @"id";
}

設置主鍵之后,對象的更新更加高效,查詢速度更快,保持唯一性。 一旦帶有主鍵的對象被添加到 Realm 之后,該對象的主鍵將不可修改。

同時,RLMObject 能夠借助 RLMObject 以及 RLMArray屬性來和另一個 RLMObject 建立關系,一對一,一對多關系。

// Dog.h
@interface Dog : RLMObject
// 其余屬性聲明...
@property Person *owner;
@end
//Dog.h
@interface Dog : RLMObject// 屬性聲明...
@end
RLM_ARRAY_TYPE(Dog) // 定義一個 RLMArray<Dog> 類型,宏創(chuàng)建了一個協(xié)議,從而允許 RLMArray<Dog> 語法的使用。

// Person.h
@interface Person : RLMObject// 其余的屬性聲明...
@property RLMArray<Dog *><Dog> *dogs;
@end

Realm數(shù)據(jù)庫操作


  • 對數(shù)據(jù)的存儲,其實就是對該對象的存儲,對對象的所有更改(添加,修改和刪除)都必須通過寫入事務(transaction)完成。Realm 的寫入操作是同步的,阻塞的,所以重復寫入是不會產(chǎn)生競爭條件的。
    注意:在存儲數(shù)據(jù)之前,必須要對對象賦值。
Person *author = [[Person alloc] init];
author.name    = @“JasonLee”;
// 獲取默認的 Realm 實例
RLMRealm *realm = [RLMRealm defaultRealm];

// 通過事務將數(shù)據(jù)添加到 Realm 中
[realm beginWriteTransaction];
[realm addObject:author];
[realm commitWriteTransaction];

  • 通過在寫入事務中將要刪除的對象傳遞給 -[RLMRealm deleteObject:] 方法,即可完成刪除操作。
    刪除存儲在 Realm 中的所有數(shù)據(jù)并不會使Realm 文件的大小改變,因為它會保留空間以供日后快速存儲數(shù)據(jù)。
// 在事務中刪除一個對象
[realm beginWriteTransaction];
[realm deleteObject:xxx];//實例對象
[realm deleteAllObjects]; // 從 Realm 中刪除所有數(shù)據(jù)
[realm commitWriteTransaction];

事務操作也可以用:

[realm transactionWithBlock:^{
  [realm deleteObject:cheeseBook];
  [realm deleteAllObjects]; 
}];

  • 對數(shù)據(jù)的修改,可以通過對其屬性值直接更新(同增),或者通過主鍵更新(當然,前提是你必須設置主鍵)。
Person *author = [[Person alloc] init];
author.name    = @“JasonLee;
author.id         = @007;

// 通過 id = 007 更新
[realm beginWriteTransaction];
[Person createOrUpdateInRealm:realm withValue:author];
[realm commitWriteTransaction];

增加也可以使用該方法,如果數(shù)據(jù)庫不存在該主鍵對象,將進行新增操作添加到數(shù)據(jù)庫。


  • 查詢默認數(shù)據(jù)庫:[類名 allObjects],返回類的所有對象
    返回類型為RLMResults
    查詢指定數(shù)據(jù)庫:
// 查詢指定的 Realm 數(shù)據(jù)庫
RLMRealm *xxxrealm = [RLMRealm realmWithPath:@”xxx.realm"];
 // 獲得一個指定的 Realm 數(shù)據(jù)庫
RLMResults *allXXX = [類名 allObjectsInRealm:xxxrealm];

條件查詢: 斷言+ 謂詞
1.使用斷言字符串查詢:

RLMResults *tanDogs = [Dog objectsWhere:@"color = '棕黃色' AND name BEGINSWITH '大'"];

2.// 使用 NSPredicate 查詢

NSPredicate *pred = [NSPredicate predicateWithFormat:@"color = %@ AND name BEGINSWITH %@”,@"棕黃色", @"大"];
RLMResults *tanDogs = [Dog objectsWithPredicate:pred];

Realm 在oc上的基礎使用就先講這些,下篇將繼續(xù)對使用個過程中出現(xiàn)的問題及優(yōu)化等作出講解。感謝您提出寶貴意見。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容