摘要:介紹是一個跨平臺移動數(shù)據(jù)庫引擎,支持和以及。添加的屬性必須是支持的基本數(shù)據(jù)類型或繼承于類型。通過查詢通過斷言查找到年的運動記錄可看作是數(shù)組修改數(shù)據(jù)通過方法將本次運動數(shù)據(jù)添加到今天運動記錄。同理,通過刪除數(shù)據(jù)。會自動進行數(shù)據(jù)結(jié)構(gòu)調(diào)整。
1.Realm介紹
realm是一個跨平臺移動數(shù)據(jù)庫引擎,支持iOS、OS X(Objective-C和Swift)以及Android。目前還支持React Native 和 Xamarin。 2014年7月發(fā)布。由YCombinator孵化的創(chuàng)業(yè)團隊歷時幾年打造,是第一個專門針對移動平臺設(shè)計的數(shù)據(jù)庫。目標(biāo)是取代SQLite。 為了徹底解決性能問題,核心數(shù)據(jù)引擎C++打造,并不是建立在SQLite之上的ORM。2.為何使用Realm
引用官網(wǎng)上性能比較數(shù)據(jù)柱狀圖,每秒能在200k條記錄的數(shù)據(jù)庫查詢到的數(shù)據(jù)記錄達到30條,Realm的性能遠超SQL、FMDB、CoreData的性能。如下:
1)Realm提供多種版本支持OC、swift等多種語言。 2)創(chuàng)建儲存對象簡單,僅需集成Realm類;或者通過Realm提供的軟件導(dǎo)入到Xcode,可以直接創(chuàng)建儲存對象,無需增加額外代碼。 3)相比SQL,不需要記住繁雜SQL語句。 4)相比CoreData,不需要架構(gòu)類與類之間的復(fù)雜關(guān)系;代碼更加簡潔。學(xué)習(xí)成本更低。3.如何使用Realm(OC版本) a. 準(zhǔn)備工作
(1) 下載最新的Realm發(fā)行版本,并解壓; (2) 前往Xcode 工程的”General”設(shè)置項中,從ios/dynamic/、osx/、tvos/或者watchos/中將’Realm.framework’拖曳到”Embedded Binaries”選項中。確認Copy items if needed被選中后,點擊Finish按鈕; (3) 在單元測試目標(biāo)的”Build Settings”中,在”Framework Search Paths”中添加Realm.framework的上級目錄; (4) 下載一個名為 Realm Browser 的獨立的Mac應(yīng)用以便 對.realm數(shù)據(jù)庫進行讀取和編輯。 (5) 安裝 Realm 插件 打開[release.zip](https://static.realm.io/downloads/objc/realm-objc-1.0.1.zip) 中的plugin/RealmPlugin.xcodeproj并進行編譯,重啟 Xcode之后插件即可生效。如果您使用 Xcode 菜單來建立一個新文件(File > New > File… — or ?N) ,您就可以看到有一個新建Realm模型的選項。b. 創(chuàng)建數(shù)據(jù)模型
如圖創(chuàng)建數(shù)據(jù)模型非常方便,跟創(chuàng)建普通的模型沒有區(qū)別。
創(chuàng)建后的.h和.m
我們需要在.h報錯的地方添加屬性以及自定義方法。添加的屬性必須是Realm支持的基本數(shù)據(jù)類型或繼承于RLMObject類型。在.m中defaltPropertyValues方法中設(shè)置默認值,在ignoredProperties方法中設(shè)置不保存到數(shù)據(jù)庫的屬性。
項目中使用場景是創(chuàng)建一個用戶User數(shù)據(jù)模型,這個模型里面保存有用戶信息、每日的運動記錄信息、還有用戶保存的拍攝視頻信息,User代碼如下:
User.h文件
#import#import "UserInforItem.h" #import "SportDayItem.h" #import "SportInforItem.h" #import "DataModel.h" #import "VideoItem.h" @interface User : RLMObject @property NSString * identification; @property UserInforItem *userInforItem; @property RLMArray *sportDayItems; @property RLMArray *videoItems; + (User *)getLastUser; - (void)addSportInforItem:(SportInforItem *)sportInforItem; @end // This protocol enables typed collections. i.e.: // RLMArray RLM_ARRAY_TYPE(User)
User.m文件
#import "User.h" #import@implementation User // Specify default values for properties + (NSDictionary *)defaultPropertyValues { return @{ @"userInforItem":@{ @"name": @"", @"location": @"", @"genderType": @0, @"height": @"170", @"weight": @"60", @"birth": @"1995-01-01", @"signature": @"智能運動,引領(lǐng)時尚", @"headIconPath": @"", @"phoneNum": @"", @"userID": @"", @"creatTime": [NSDate date], @"lasLoginTime": @"", @"lastLoginVersion": @"", @"isWiFi":@NO }, @"sportDayItems":@[], @"videoItems":@[] }; } + (NSString *)primaryKey { return @"identification"; } #pragma mark - Public Method + (User *)getLastUser { NSString *identification = [DataModel lastLoginID]; User *user = [User objectForPrimaryKey:identification]; if (user == nil) { user = [[User alloc] init]; user.identification = [DataModel lastLoginID]; RLMRealm *realm = [RLMRealm defaultRealm]; [realm beginWriteTransaction]; [realm addObject:user]; [realm commitWriteTransaction]; } return user; } - (void)addSportInforItem:(SportInforItem *)sportInforItem { BOOL isHaveTodaySportRecord = NO; for (SportDayItem *dayItem in self.sportDayItems) { if ([dayItem.sportDate dayOfYear] == [sportInforItem.creatTime dayOfYear]) { isHaveTodaySportRecord = YES; RLMRealm *realm = [RLMRealm defaultRealm]; [realm beginWriteTransaction]; [dayItem.sportInforArray addObject:sportInforItem]; [realm commitWriteTransaction]; break; } } if (!isHaveTodaySportRecord) { SportDayItem *dayItem = [[SportDayItem alloc] init]; dayItem.sportDate = sportInforItem.creatTime; [dayItem.sportInforArray addObject:sportInforItem]; RLMRealm *realm = [RLMRealm defaultRealm]; [realm beginWriteTransaction]; [self.sportDayItems addObject:dayItem]; [realm commitWriteTransaction]; } } // Specify properties to ignore (Realm won"t persist these) //+ (NSArray *)ignoredProperties //{ // return @[]; //} @end
Realm支持以下的屬性類型:BOOL、bool、int、NSInteger、long、long long、float、double、NSString、NSDate、NSData 以及 被特殊類型標(biāo)記的 NSNumber 。 CGFloat 屬性的支持被取消了,因為它的類型不依賴于平臺。 您可以使用RLMArray
User.h的identification屬性作為主鍵,需要在.m的+ (NSString *)primaryKey 返回identification屬性名。
+ (NSString *)primaryKey { return @"identification"; }
實現(xiàn)defaultPropertyValues方法,需要返回屬性名的鍵值對字典。創(chuàng)建User數(shù)據(jù)模型時,會自動設(shè)置這些屬性的默認值。若不需要設(shè)置默認值,則可以注釋該方法。
+ (NSDictionary *)defaultPropertyValues { return @{ @"userInforItem":@{ @"name": @"", @"location": @"", @"genderType": @0, @"height": @"170", @"weight": @"60", @"birth": @"1995-01-01", @"signature": @"智能運動,引領(lǐng)時尚", @"headIconPath": @"", @"phoneNum": @"", @"userID": @"", @"creatTime": [NSDate date], @"lasLoginTime": @"", @"lastLoginVersion": @"", @"isWiFi":@NO }, @"sportDayItems":@[], @"videoItems":@[] }; }
某些場景中,數(shù)據(jù)模型的一些屬性僅作為中間變量,不需要保存到數(shù)據(jù)庫中。這時候我們可以實現(xiàn)ignoredProperties方法,返回一個數(shù)組包含對應(yīng)的屬性名即可。
// Specify properties to ignore (Realm won"t persist these) //+ (NSArray *)ignoredProperties //{ // return @[]; //}
(1)通過主鍵查找
+ (User *)getLastUser { NSString *identification = [DataModel lastLoginID]; User *user = [User objectForPrimaryKey:identification]; if (user == nil) { user = [[User alloc] init]; user.identification = [DataModel lastLoginID]; RLMRealm *realm = [RLMRealm defaultRealm]; [realm beginWriteTransaction]; [realm addObject:user]; [realm commitWriteTransaction]; } return user; }
通過objectForPrimaryKey方法從數(shù)據(jù)庫中獲取到User,如果取出來的是nil,就通過如下方法拿到數(shù)據(jù)庫單例,執(zhí)行beginWriteTransaction方法和
commitWriteTransaction方法添加新的user對象到數(shù)據(jù)庫。需要注意的是beginWriteTransaction方法和commitWriteTransaction方法要配對使用,否則不能存到數(shù)據(jù)庫。
RLMRealm *realm = [RLMRealm defaultRealm]; [realm beginWriteTransaction]; [realm addObject:user]; [realm commitWriteTransaction];
(2)通過NSPredicate查詢
通過斷言查找到2016年的運動記錄,RLMResults可看作是數(shù)組
NSPredicate *pred = [NSPredicate predicateWithFormat:@"dayOfYear = %@,@"2016"]; RLMResults *thisYearSportItems = [sportDayItems objectsWithPredicate:pred];
通過addObject方法將本次運動數(shù)據(jù)添加到今天運動記錄。同理,通過deleteObject刪除數(shù)據(jù)。
RLMRealm *realm = [RLMRealm defaultRealm]; [realm beginWriteTransaction]; [dayItem.sportInforArray addObject:sportInforItem]; [realm commitWriteTransaction];
當(dāng)數(shù)據(jù)模型增加新屬性或者修改屬性都需要進行數(shù)據(jù)庫遷移。在Appdelegate的didFinishLaunchingWithOptions方法中實現(xiàn)如下代碼:
#pragma mark - 數(shù)據(jù)庫遷移 - (void)migrationRealm { RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration]; config.schemaVersion = 2; config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) { // 目前我們還未進行數(shù)據(jù)遷移,因此 oldSchemaVersion == 0 if (oldSchemaVersion < 1) { //低于版本1,執(zhí)行相應(yīng)遷移代碼(按版本遷移代碼:按需可選,若增加新屬性或刪除,可不寫) } if (oldSchemaVersion < 2) { //低于版本2,執(zhí)行相應(yīng)遷移代碼(按版本遷移代碼:按需可選,若增加新屬性或刪除,可不寫) } }; [RLMRealmConfiguration setDefaultConfiguration:config]; [RLMRealm defaultRealm]; }
Realm進行數(shù)據(jù)遷移是非常方便的。需要把數(shù)據(jù)庫版本+1.如果只是增加或刪除屬性,按版本的遷移代碼不需要寫。Realm會自動進行數(shù)據(jù)結(jié)構(gòu)調(diào)整。按版本遷移代碼是高級特性,使用場景是把數(shù)據(jù)模型的幾個舊屬性合并成一個新屬性。
PS:沒有進行遷移的數(shù)據(jù)庫版本schemaVersion為0,第一次遷移的數(shù)據(jù)庫版本設(shè)置為1.
結(jié)語Realm數(shù)據(jù)庫是一個面向?qū)ο?、簡單易用,性能強大的?shù)據(jù)庫,還有很多高級特性需要慢慢學(xué)習(xí)。個人覺得學(xué)習(xí)成本較低,用起來比較順手的,加入項目中僅增加1M。但剛開始的時候很容易踩坑,因為Realm報錯信息經(jīng)常讓人摸不著邊。如在使用Realm的過程中遇到任何難解問題,或者你有更好的Realm使用技巧,均可留言互相交流探討。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/17730.html
摘要:事件雖然不支持,但它支持事件,該事件的目的是提供與文檔或元素的加載狀態(tài)有關(guān)的信息。事件可以用于檢測是否加載完畢,當(dāng)時,表示加載完成。封裝事件以下,是封裝事件從而達到良好的兼容性的一個簡單的代碼實現(xiàn)。 我們在開發(fā)時,經(jīng)常需要檢測頁面是否加載完畢,以確保腳本安全運行,下面我們就來淺談一下檢測頁面是否加載完畢的那些事件們。 1. onload 事件 在頁面的所有資源加載完成時,window對...
摘要:事件雖然不支持,但它支持事件,該事件的目的是提供與文檔或元素的加載狀態(tài)有關(guān)的信息。事件可以用于檢測是否加載完畢,當(dāng)時,表示加載完成。封裝事件以下,是封裝事件從而達到良好的兼容性的一個簡單的代碼實現(xiàn)。 我們在開發(fā)時,經(jīng)常需要檢測頁面是否加載完畢,以確保腳本安全運行,下面我們就來淺談一下檢測頁面是否加載完畢的那些事件們。 1. onload 事件 在頁面的所有資源加載完成時,window對...
摘要:的特點模塊化會把一切視為模塊,而模塊化的文件會十分靈活,且容易調(diào)試以及升級,會讓人有種工程化的意識。的安裝形式安裝也可以直接安裝到項目的依賴里配置入口文件模塊打包的起點稱之為入口文件。是你第一個啟動的文件。 好多人在剛開始學(xué)習(xí)了webpack之后,可能對于webpack是什么?怎么用多少會有些迷茫,下面是我的學(xué)習(xí)心得,希望能幫助到大家,有不足之處,也歡迎提出共同來討論。 webpack...
閱讀 1668·2019-08-29 13:53
閱讀 3259·2019-08-29 13:50
閱讀 906·2019-08-27 10:51
閱讀 636·2019-08-26 18:36
閱讀 1936·2019-08-26 11:00
閱讀 664·2019-08-26 10:36
閱讀 3276·2019-08-23 17:58
閱讀 2078·2019-08-23 15:17