iOS realm


第一個專門針對移動平臺設計的數據庫。Realm是一個跨平臺的移動數據庫引擎,目前支持iOS、Android平臺,同時支持Objective-C、Swift、Java、React Native、Xamarin等多種編程語言。Realm自發布之初就提出了:“reaml是SQLite以及CoreData的替代者”的口號。

簡介

Realm是一個跨平臺的移動數據庫引擎,於2014年7月發佈,準確來說,它是專門爲移動應用所設計的數據持久化解決方案。Realm並不是對SQLite或者CoreData的簡單封裝,它建立了自己獨特的數據庫存儲引擎,可以方便、高效的完成數據庫的各種操作。

Realm是一款專門針對移動平臺設計的數據庫,因此其能夠無縫的支持iOS以及Android,並且支持Objective-C、Swift、Java、React Native等多種編程語言編寫。

與SQLite或者CoreData相比,Realm最大的優勢在於學習門檻極低,由於其是直接針對對象進行讀寫的,因此,不必像SQLite一樣,需要預先掌握SQL語句,也不像CoreData使用起來如此的繁瑣。

Realm不僅學習難度極低,其還擁有不凡的性能,根據Realm官方提供的數據如下所示:

  • 統計查詢。針對20萬條數據執行統計操作,Realm每秒可以執行30.9次統計操作
    在這裏插入圖片描述
  • 遍歷查詢。針對20萬條數據,Realm每秒可以遍歷31次查詢
    在這裏插入圖片描述
  • 插入操作。Realm的性能雖然低於原生的SQLite,但是卻遠遠高於FMDB以及CoreData
    在這裏插入圖片描述
    有關Realm更多的介紹,可以訪問官方網站:https://realm.io

Realm的優勢與亮點

在這裏插入圖片描述

  • 開源。Realm移動端數據庫相關代碼已全部開源。數千開發者在GitHub上參與了相關工作。另外還有幾百個Realm數據庫相關的擴展。
  • 簡單易用:Core Data 、 SQLite 龐大的學習量和繁雜的代碼足以嚇退絕大多數剛入門的開發者,而換用 Realm,則可以極大地減少學習代價和學習時間,讓應用及早用上數據存儲功能。
  • 跨平臺:現在絕大多數的應用開發並不僅僅只在 iOS 平臺上進行開發,還要兼顧到 Android 平臺的開發。爲兩個平臺設計不同的數據庫是不明智的,而使用 - - Realm 數據庫,iOS 和 Android 無需考慮內部數據的架構,調用 Realm 提供的 API 就可以完成數據的交換,實現“一個數據庫,兩個平臺無縫銜接”。
  • 線程安全。程序員無需對在不同線程中,對數據庫的讀取一致性做任何考慮,Realm會保證每次讀取都得到一致的數據。

Realm Browser

爲了配合Realm的使用,Realm還提供了一個輕量級的數據庫查看工具Realm Browser,藉助這個工具,開發者可以查看數據庫當中的內容,並執行簡單的插入和刪除操作。Realm Browser可以在App Store中下載安裝。
在這裏插入圖片描述
我們可以在Realm Browser中選擇Tools -> Generate demo database來創建一個測試數據庫,來實踐一下Realm Browser的功能。
在這裏插入圖片描述

Realm中的一些重要概念

爲了掌握Realm的使用,需要預先了解並掌握Realm中的一些重要概念以及類。

  • RLMRealm類:可以理解爲Realm創建的用於數據存儲的數據庫類,與CoreData中的管理上下文(managed object context)類似。對於存儲在Realm中的數據,我們都需要獲取到一個RLMRealm類的對象,然後對其中的數據進行讀寫操作。
  • RLMObject類:對於Realm中存儲的對象,都是RLMObject類的子類,也就是說,RLMRealm類中存儲的都是RLMObject類的對象。
  • RLMResults類:對Realm數據庫執行查詢操作後,返回的結果是一個
  • RLMResults對象,這個對象是一個數組,其中存儲的對象都是RLMObject類型的。不僅如此,它還擁有許多更強大的功能,包括排序、查找等等操作。
    寫操作事務(Write Transactions):Realm數據庫中的所有操作,比如創建、編輯,或者刪除對象,都必須在事務中完成。

Realm的安裝-CocoaPods

當使用CocoaPods方式安裝Realm時,可以按照如下步驟進行。

安裝CocoaPods 0.39.0 或者更高版本;
在Podfile中,添加pod 'Realm’到您的 app 目標中,添加pod 'Realm/Headers’到您的測試目標中;
在終端運行pod install;
採用 CocoaPods 生成的.xcworkspace來運行工程!
不論是採用手工方式導入Realm,還是使用CocoaPods方法導入,在需要使用Realm的 Objective-C 源文件的頂部,使用 *#import <Realm/Realm.h> *來導入 Realm,以便在代碼中使用。

Xcode插件

Realm提供了一個Xcode插件,來方便的創建RLMObject類,這需要我們首先安裝相關的插件。安裝的方法是:打開Realm文件夾中的plugin/RealmPlugin.xcodeproj並進行編譯,重啓 Xcode之後插件即可生效。
在這裏插入圖片描述
當需要新建RLMObject類時,在新建類的選項中選擇Realm Model Object即可。
在這裏插入圖片描述

常用屬性和方法

在Realm框架中,定義了大約二十個類,常用的如:RLMRealm類、RLMObject類、RLMResults類等,我們需要掌握幾個核心類中定義的屬性以及方法,即可開始使用Realm。

Realm的類定義說明

在Realm框架中,定義了二十個核心類、常量、枚舉類型、協議等,我們可以從Realm的官方網站上查看所有的定義以及使用說明,查看地址:https://realm.io/docs/objc/latest/api/Constants.html。

RLMRealm類

一個RLMRealm類的對象可以認爲是一個Realm的數據庫。Realm數據庫既可以存儲在硬盤上,同時也可以存儲在內存中。RLMRealm類中,常用的屬性或方法如下。

獲取默認的Realm數據庫

+ (instancetype)defaultRealm;

實例化一個RLMRealm類的對象

+ (nullable instancetype)realmWithConfiguration:(RLMRealmConfiguration *)configuration error:(NSError **)error;
+ (instancetype)realmWithPath:(NSString *)path;

對Realm數據庫進行讀寫操作

- (void)beginWriteTransaction;
- (void)commitWriteTransaction;
- (BOOL)commitWriteTransaction:(NSError **)error;
- (void)cancelWriteTransaction;
- (void)transactionWithBlock:(__attribute__((noescape)) void(^)(void))block;

添加或更新對象

- (void)addObject:(RLMObject *)object;
- (void)addOrUpdateObject:(RLMObject *)object;

刪除對象

- (void)deleteObject:(RLMObject *)object;
- (void)deleteObjects:(id)array;
- (void)deleteAllObjects;

RLMObject類

在Realm數據庫中存儲的都是RMObject對象,RLMObject類是所有可以存儲在Realm數據庫中的對象的根類,也就是說,凡是可以存儲在Realm數據庫中的對象都是RLMObject類或RLMObject類的子類。在RLMObject類中,我們可以添加屬性,添加的屬性類型可以支持如下類型:

NSString:字符串
NSInteger, int, long, float, and double:數字型,注意沒有CGFloat
BOOL / bool:布爾型
NSDate:日期型
NSData:二進制字符型
NSNumber:其中X必須是 RLMInt, RLMFloat, RLMDouble 或 RLMBool類型
RLMObject的子類
RLMArray:其中X必須是RLMObject類的子類.

RLMObject類中,比較常用如下方法:
在Realm數據庫中,獲取該RLMObject類的所有對象

+ (RLMResults *)allObjects;

根據查詢條件返回滿足條件的所有RLMObject類的對象

+ (RLMResults *)objectsWhere:(NSString *)predicateFormat, ...;

RLMResults類

當我們執行一個查詢操作後,查詢出滿足條件的RLMObject對象會存放在一個RLMResults對象中。RLMResults類是一個數組類型的數據結構,因此在其類定義中,提供了很多與數組類似的屬性和方法。

根據索引index獲取其中的某個對象

- (RLMObjectType)objectAtIndex:(NSUInteger)index;

返回RLMResults對象中存儲的RLMObject對象數量

@property (nonatomic, readonly, assign) NSUInteger count;

返回RLMResults對象中的第一個RLMObject對象

- (nullable RLMObjectType)firstObject;

返回RLMResults對象中的最後一個RLMObject對象

- (nullable RLMObjectType)lastObject;

根據對象返回其索引

- (NSUInteger)indexOfObject:(RLMObjectArgument)object;

使用舉例

創建RLMObject類

在這裏插入圖片描述
在這裏插入圖片描述
在WebSite.h中,我們添加兩個屬性webName和html,都是NSString類型的。需要大家注意的是,在RLMObject類中添加的屬性,是不需要指定屬性關鍵字的,完全交由Realm處理

#import <Realm/Realm.h>
@interface WebSite : RLMObject
@property NSString *webName;
@property NSString *html;
@end
RLM_ARRAY_TYPE(WebSite)

存儲操作

對於RLMObject類型的對象,我們可以直接對創建的對象進行存儲。

  • 第一步,創建對象。例如,我們創建兩個WebSite類的對象。
WebSite *webSite1 = [[WebSite alloc] init];
    webSite1.webName = @"baidu";
    webSite1.html = @"https://www.baidu.com";
    
    WebSite *webSite2 = [[WebSite alloc] init];
    webSite2.webName = @"sina";
    webSite2.html = @"http://www.sina.com.cn";
  • 第二步,寫入Realm數據庫。我們需要獲取一個Realm數據庫,然後在一個事務中調用addObject:方法,即可把一個對象寫入到Realm數據庫中.
RLMRealm *realm = [RLMRealm defaultRealm];
    [realm transactionWithBlock:^{
        [realm addObject:webSite1];
        [realm addObject:webSite2];
    }];

查詢操作

Realm中也提供了功能強大的數據查詢能力,如果會使用SQL語言的話,上手的難度更低。在Realm的查詢功能中,也可以像SQL一樣使用各種條件查詢關鍵字,查詢的結果會保存在一個RLMResults類的數組中。

  • 全量查詢。通過調用allObjects方法,即可從Realm數據庫中,獲取存儲的某個RLMObject子類的所有對象,這類似於SQL中從某張表中查詢得到該表中的所有數據。
   RLMResults <WebSite *> *webSites = [WebSite allObjects];
    NSLog(@"webSites count:%lu",(unsigned long)webSites.count);
  • 條件查詢。我們可以使用objectsWhere:方法,設置一些查詢條件,從而查詢出符合條件的對象。Realm的查詢條件可以使用==、<=、<、>=、>、!=、BETWEEN、CONTAINS 以及 ENDSWITH等多種操作符。

更新操作

當我們需要對Realm中存儲的對象進行更新修改操作時,我們首先需要查詢出滿足修改條件的對象,然後調用beginWriteTransaction方法,開啓一個寫事務,然後對對象的屬性進行修改,修改完成後需要調用commitWriteTransaction方法提交事務。例如,下方的代碼查詢出webName是sina的對象,並對其屬性進行修改。

RLMResults <WebSite *> *webSitesWithCondition = [WebSite objectsWhere:@"webName == 'sina'"];
    WebSite *webSite = [webSitesWithCondition firstObject];
    RLMRealm *realm = [RLMRealm defaultRealm];
    [realm beginWriteTransaction];
    webSite.webName = @"baidu";
    webSite.html = @"http://www.baidu.com";
    [realm commitWriteTransaction];

刪除操作

當需要在Realm中刪除某些對象時,可以調用deleteObjects:方法,需要注意的是,該方法的執行需要在一個事務中進行。例如,下方的代碼查詢出所有webName爲baidu的對象,並從Realm數據庫中刪除。

RLMResults <WebSite *> *webSitesWithCondition = [WebSite objectsWhere:@"webName == ''baidu"];
    RLMRealm *realm = [RLMRealm defaultRealm];
    [realm transactionWithBlock:^{
    [realm deleteObjects:webSitesWithCondition];
    }];

使用Realm Browser查看Realm數據庫內容

Realm默認的數據庫保存在App的沙盒中,我們可以通過Realm Browser查看其中存儲的內容。
在這裏插入圖片描述

代碼

https://github.com/ShaeZhuJiu/realm_base.git

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章