Realm

一、環境配置

1.1 安裝Realm

  • GitHub下載
  • CocoaPods

1.2 Xcode插件

下載完打開plugin/RealmPlugin.xcodeproj並運行,重啓Xcode,新建一個RLMObject類,如下:

RLMObject

1.3 Realm Browser(可視化工具 )

App Store中下載安裝 Realm Browser,幫助更好查看數據的增刪改查

二、實踐&原理

2.1 模型屬性

Post

Post.h
#import <Realm/Realm.h>
@class User; // 避免交叉引用

RLM_ARRAY_TYPE(Post)

@interface Post : RLMObject

@property User *user; // 對一

@property NSString *postID;
@property NSString *title;
@property NSDate *timestamp;
@property NSData *content;
@property NSInteger look; // defaultPropertyValues
@property NSNumber<RLMBool> *isTop; // 常量在Realm數據庫裏邊是不可以爲空,所以存儲爲NSNumber
@property RLMArray <Post *><Post> *comments; // 對多

// 不支持CGFloat,請使用float和double

@end
Post.m
#import "Post.h"

@implementation Post

// 可空屬性,決定屬性是否可以爲nil
+ (NSArray<NSString *> *)requiredProperties {
    return @[@"title"];
}

+ (NSDictionary *)defaultPropertyValues {
    return @{
             @"look": @(0)
             };
}

// 忽略屬性
+ (NSArray *)ignoredProperties {
    return @[];
}

// 索引屬性,支持NSString,NSNumber(包括常量),NSDate
+ (NSArray<NSString *> *)indexedProperties {
    return @[@"title", @"timestamp"];
}

// 主鍵(唯一性)
+ (NSString *)primaryKey {
    return @"postID";
}

User

User.h
#import <Realm/Realm.h>

@interface User : RLMObject

@property NSString *nickName;
@property NSString *hobby;
@property (readonly) RLMLinkingObjects *posts; // 對多(RLMLinkingObjects繼承自RLMResults)

@end

// This protocol enables typed collections. i.e.:
// RLMArray<User *><User>
RLM_ARRAY_TYPE(User)
User.m
+ (NSDictionary<NSString *,RLMPropertyDescriptor *> *)linkingObjectsProperties {
    return @{
             @"posts": [RLMPropertyDescriptor descriptorWithClass:Post.class propertyName:@"user"]
             };
}

Test

Post *post = [[Post alloc] initWithValue:@{@"postID": @"5201314", @"title": @"undefined"}];
User *user = [[User alloc] init];
user.hobby = @"tennis";
post.user = user;

RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
    [realm addObject:post];
    [realm addObject:user];
    
    NSLog(@"%@", user.posts);
}];

2.2 數據庫操作

[realm transactionWithBlock:^{
    [realm addObject:post]; // 增
}];

[realm transactionWithBlock:^{
    [realm deleteObject:post];
    [realm deleteAllObjects]; // 刪
}];

針對某個對象修改&實時性
[realm transactionWithBlock:^{
    post.timestamp = [NSDate date]; // 改
}];
通過主鍵更新
Post *postReset = [[Post alloc] init];
postReset.postID = @"52011314";
postReset.title = @"真香";
postReset.timestamp = [NSDate date];
[realm transactionWithBlock:^{
   [realm addOrUpdateObject:postReset];
}];
批量修改(支持KVC)
RLMResults *results = [Post allObjects];
[realm transactionWithBlock:^{
    [results setValue:[NSDate date] forKey:@"timestamp"];
}];

等於
RLMResults *results = [Post objectsWhere:@"title == %@", @"undefined"];

Post *postBeFound = [results firstObject];

[realm transactionWithBlock:^{
    post.title = @"hihihi";
}];

NSLog(@"%@", postBeFound);
大於小於
// AND
RLMResults *results = [Post objectsWhere:@"look < 20 AND look > 0"];

// BETWEEN
RLMResults *results = [Post objectsWhere:@"look BETWEEN {10, 80}"];
包含
// [c]不區分大小寫
 RLMResults *results = [Post objectsWhere:@"title CONTAINS[c] 'hi'"];
鏈式檢索
RLMResults *results = [Post objectsWhere:@"comments.@count > 0"];
RLMResults *finalResults = [results objectsWhere:@"look > 10"];
NSLog(@"%@", finalResults);
排序
// 不影響數據庫中的排序
RLMResults *results = [Post allObjects];
RLMResults *sortResult = [results sortedResultsUsingKeyPath:@"look" ascending:YES];
NSLog(@"%@", sortResult);
分頁

沒有分頁功能,通過惰性加載

2.3 數據庫基本配置

查看路徑及相關配置:

RLMRealmConfiguration *defaultRealm = [RLMRealmConfiguration defaultConfiguration];
NSLog(@"%@", defaultRealm);

打印:

打印結果

其中幾個參數:

參數 意義
inMemoryIdentifier
encryptionKey
readOnly
schemaVersion
deleteRealmIfMigrationNeeded
shouldCompactOnLaunch
dynamic
customSchema
RLMRealmConfiguration *defaultRealm = [RLMRealmConfiguration defaultConfiguration];
defaultRealm.fileURL = [[NSBundle mainBundle] URLForResource:@"default" withExtension:@"realm"];
defaultRealm.readOnly = YES;
RLMRealm *realm = [RLMRealm realmWithConfiguration:defaultRealm error:nil];
// 內存數據庫
RLMRealmConfiguration *memoryRealm = [RLMRealmConfiguration defaultConfiguration];
memoryRealm.inMemoryIdentifier = @"memoryDB";
RLMRealm *realmMem = [RLMRealm realmWithConfiguration:memoryRealm error:nil];

// 數據庫寫入通知

2.4 數據庫版本遷移

RLMRealmConfiguration *realmConf = [RLMRealmConfiguration defaultConfiguration];
uint64_t currentVersion = 3;
realmConf.schemaVersion = currentVersion;
[realmConf setMigrationBlock:^(RLMMigration * _Nonnull migration, uint64_t oldSchemaVersion) {
   if(oldSchemaVersion < currentVersion) {
       [migration enumerateObjects:NSStringFromClass([Post class]) block:^(RLMObject * _Nullable oldObject, RLMObject * _Nullable newObject) {
           newObject[@"hot"] = @([oldObject[@"look"] integerValue]);
       }];

       // 屬性重命名
       [migration renamePropertyForClass:NSStringFromClass([Post class]) oldName:@"title" newName:@"postTitle"];
   }
}];
RLMRealm *realm = [RLMRealm realmWithConfiguration:realmConf error:nil];

在這裏插入圖片描述
在這裏插入圖片描述
常量在RLM數據庫中不能爲空

三、比較

RLMObject 與 NSManagerObject

不可重寫setter和getter
RLMObject:支持ignore屬性;NSManagerObject需要@dynamic屬性

【參考】

1、官方文檔

2、Realm數據庫 從入門到“放棄”

3、手把手教你從Core Data遷移到Realm

4、iOS Realm簡單使用(增刪改查和排序)

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