Realm是專門為移動(dòng)端開發(fā)的數(shù)據(jù)庫(kù)引擎逞带。它具有跨平臺(tái)欺矫,簡(jiǎn)單易用,速度快展氓,占用空間小穆趴,支持java,objec-c遇汞,swift語(yǔ)言等特點(diǎn)未妹,迅速的得到了開發(fā)者的青睞。項(xiàng)目中使用了Realm勺疼,將中間的過(guò)程記錄下來(lái)以備查閱教寂。
環(huán)境
- 系統(tǒng):OS X 10.11.5捏鱼,
- Xcode:Version 7.2 (7C68)
- 開發(fā)語(yǔ)言:Objective-C
準(zhǔn)備
1.下載Realm對(duì)應(yīng)的Objective-C版本执庐。下載地址在這里,選擇realm-cocoa下載源代碼导梆。
2.將Realm集成到項(xiàng)目轨淌。
Realm框架支持常用的靜態(tài)庫(kù),動(dòng)態(tài)庫(kù)看尼,CocoaPads和Carthage 幾種集成方式递鹉。
本文使用動(dòng)態(tài)庫(kù)的方式。-
首先將下載 Realm 的最新版本并解壓;解壓后文件如下
前往Xcode 工程的”General”設(shè)置項(xiàng)中藏斩,從ios/dynamic/中將’Realm.framework’拖曳到”Embedded Binaries”選項(xiàng)中躏结。確認(rèn)Copy items if needed被選中后,點(diǎn)擊Finish按鈕狰域;
-
在項(xiàng)目的”Build Phases”中媳拴,創(chuàng)建一個(gè)新的”Run Script Phase”黄橘,并將
bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework/strip-frameworks.sh"
這條腳本復(fù)制到文本框中。
-
下載Realm Browser的Mac應(yīng)用以便 對(duì).realm數(shù)據(jù)庫(kù)進(jìn)行讀取和編輯屈溉。
同時(shí)Xcode也有個(gè)Realm Browser的插件塞关。使用Alcatraz安裝即可。由于我使用的Xcode7.2版本子巾。會(huì)不支持該插件出現(xiàn)想這樣的錯(cuò)誤帆赢。
PluginLoading: Required plug-in compatibility UUID F41BD31E-2683-44B8-AE7F-5F09E919790E for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/RealmBrowser.xcplugin' not present in DVTPlugInCompatibilityUUIDs```
解決辦法:找到該插件的配置文件,將7.2的UUID添加到配置文件即可线梗。
+ 安裝Xcode 插件
RealmPlugin插件可以快速的創(chuàng)建基于RLMObject的模型對(duì)象椰于。
![](http://upload-images.jianshu.io/upload_images/1101711-6a8c11404f0cb0f0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
安裝完成后,直接command + N新建對(duì)應(yīng)的模型文件仪搔。
![](http://upload-images.jianshu.io/upload_images/1101711-a5af9f65646bfa79.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
####Realm數(shù)據(jù)模型
Realm數(shù)據(jù)模型是基于標(biāo)準(zhǔn) Objective-C 類來(lái)進(jìn)行定義的廉羔,使用屬性來(lái)完成模型的具體定義。
通過(guò)簡(jiǎn)單的繼承 RLMObject 或者一個(gè)已經(jīng)存在的模型類僻造,您就可以創(chuàng)建一個(gè)新的 Realm 數(shù)據(jù)模型對(duì)象憋他。
構(gòu)建一個(gè)銀行卡模型BankInfo
import <Foundation/Foundation.h>
import <Realm/Realm.h>
@interface BankInfo : RLMObject
//銀行卡信息
@property (nonatomic, copy) NSString *bank_accnoalias;
@property (nonatomic, copy) NSString *bank_accname;
@property (nonatomic, copy) NSString *bankname;
@property (nonatomic, copy) NSString *bankid;
@property (nonatomic, copy) NSString *status;
@property (nonatomic, copy) NSString *acc_nature;
@property (nonatomic, copy) NSString *bank_accno;
+(instancetype)bankInfoWithDict:(NSDictionary * )dict;
-(instancetype)initWithBankDict:(NSDictionary *)dict;
@end
RLM_ARRAY_TYPE(BankInfo)
構(gòu)建持卡人模型Person
import <Realm/Realm.h>
import "BankInfo.h"
@interface Person : RLMObject
@property NSString *name;
@property RLMArray<BankInfo> *banks;
@end
+ 其中在BankInfo模型類的聲明的結(jié)尾使用RLM_ARRAY_TYPE(BankInfo)宏來(lái)創(chuàng)建一個(gè)協(xié)議,從而允許 RLMArray<BankInfo> 語(yǔ)法的使用髓削。
然后在Person模型類中聲明屬性```@property RLMArray<BankInfo> *banks;```這樣兩個(gè)類構(gòu)建成了一對(duì)多的關(guān)系竹挡。
> 如果是互相包含的關(guān)系呢?
在Realm中通過(guò)反向關(guān)系來(lái)實(shí)現(xiàn)即:
```@property (readonly) RLMLinkingObjects *owners;```
先在BankInfo模型類聲明聲明owners屬性立膛,然后重寫 +[RLMObject linkingObjectsProperties] 來(lái)指明關(guān)系揪罕,說(shuō)明 ownders 中包含了 Person 模型對(duì)象。
具體代碼
@interface BankInfo : RLMObject
@property (readonly) RLMLinkingObjects *owners;
@end
RLM_ARRAY_TYPE(BankInfo)
@implementation BankInfo
- (NSDictionary *)linkingObjectsProperties
{
return @{ @"owners": [RLMPropertyDescriptor descriptorWithClass:Person.class propertyName:@"banks"] };
}
@end
@interface Person : RLMObject
@property NSString *name;
@property RLMArray< BankInfo > *banks;
@end
@implementation Person
@end
+ Realm支持以下的屬性類型:BOOL宝泵、bool好啰、int、NSInteger儿奶、long框往、long long、float闯捎、double椰弊、NSString、NSDate瓤鼻、NSData 以及 被特殊類型標(biāo)記的 NSNumber 秉版。CGFloat 屬性的支持被取消了,因?yàn)樗念愋筒灰蕾囉谄脚_(tái)茬祷。
+ 模型類屬性是否可以為nil
@interface Person : RLMObject
@property NSString *name;
@property NSDate *birthday;
@end
@implementation Person
- (NSArray *)requiredProperties {
return @[@"name"];
}
@end
重寫了requiredProperties方法代表name不能為nil
+ 添加索引
重寫 +indexedProperties 方法可以為數(shù)據(jù)模型中需要添加索引的屬性建立索引
@interface Book : RLMObject
@property float price;
@property NSString *title;
@end
@implementation Book
- (NSArray *)indexedProperties {
return @[@"title"];
}
@end
Realm 支持字符串清焕、整數(shù)、布爾值以及 NSDate 屬性作為索引。
+ 添加屬性默認(rèn)值
重寫+defaultPropertyValues可以在每次對(duì)象創(chuàng)建之后為其提供默認(rèn)值秸妥。
@interface Book : RLMObject
@property float price;
@property NSString *title;
@end
@implementation Book
- (NSDictionary *)defaultPropertyValues {
return @{@"price" : @0, @"title": @""};
}
@end
+ 設(shè)置主鍵
重寫 +primaryKey 可以設(shè)置模型的主鍵借卧。聲明主鍵之后,對(duì)象將被允許查詢筛峭,更新速度更加高效铐刘,并且要求每個(gè)對(duì)象保持唯一性。 一旦帶有主鍵的對(duì)象被添加到 Realm 之后影晓,該對(duì)象的主鍵將不可修改镰吵。
@interface Person : RLMObject
@property NSInteger id;
@property NSString *name;
@end
@implementation Person
- (NSString *)primaryKey {
return @"id";
}
@end
+ 忽略屬性
重寫 +ignoredProperties 可以防止 Realm 存儲(chǔ)數(shù)據(jù)模型的某個(gè)屬性
@interface Person : RLMObject
@property NSInteger tmpID;
@property (readonly) NSString *name; // 只讀屬性將被自動(dòng)忽略
@property NSString *firstName;
@property NSString *lastName;
@end
@implementation Person
- (NSArray *)ignoredProperties {
return @[@"tmpID"];
}
- (NSString *)name {
return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
}
@end
####Realm集合
Realm 擁有一系列能夠幫助表示一組對(duì)象的類型,我們稱之為『Realm 集合』:
RLMResults類挂签,表示從檢索 中所返回的對(duì)象集合疤祭。
RLMArray類,表示模型中的對(duì)多關(guān)系饵婆。
RLMLinkingObjects類勺馆,表示模型中的反向關(guān)系。
RLMCollection協(xié)議侨核,定義了所有 Realm 集合所需要遵守的常用接口草穆。
####Realm增刪改查
將常用的增刪改查進(jìn)行封裝,代碼如下搓译。
// 構(gòu)建Realm數(shù)據(jù)庫(kù)
RLMRealm *realm = [RLMRealm defaultRealm];
RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
[RLMRealmConfiguration setDefaultConfiguration:config];
// Realm內(nèi)存數(shù)據(jù)庫(kù)
//RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
//config.inMemoryIdentifier = @"MyInMemoryRealm";
//RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:nil];
//self.rlmRealm = realm;// 在使用Realm內(nèi)存數(shù)據(jù)庫(kù)的時(shí)候悲柱,必須使用強(qiáng)指針引用,如果某個(gè)內(nèi)存 Realm 數(shù)據(jù)庫(kù)實(shí)例沒(méi)有被引用些己,那么所有的數(shù)據(jù)就會(huì)被釋放豌鸡。
// 增加數(shù)據(jù)
-
(BOOL)realmsInsertData:(NSArray *)data{
NSError *error;
// Add an object
[self.rlmRealm beginWriteTransaction];
for (int i = 0; i < data.count; i++) {BankInfo *obj = [[BankInfo alloc] initWithBankDict:data[i]]; [self.rlmRealm addOrUpdateObject:obj];
}
return [self.rlmRealm commitWriteTransaction:&error];
}
// 查詢數(shù)據(jù)
-
(id)realmSelectData:(NSString *)object theCondition:(NSString *)condition{
Class cls = NSClassFromString(object);
RLMResults *result = [cls objectsInRealm:self.rlmRealm where:condition];
return result;
}
// 刪除數(shù)據(jù)
-
(BOOL)realmsDeleteData:(NSString *)object theCondition:(NSString *)condition type:(realmDelType)type{
Class cls = NSClassFromString(object);
if (cls == nil) {
return NO;
}
RLMResults *results = [self realmsselectData:[BankInfo className] theCondition:condition];
if (!results.count) {
return YES;
}
NSError *error = nil;
// 開始事務(wù)
[self.rlmRealm beginWriteTransaction];
switch (type) {
case realmDelTypeAll:
[self.rlmRealm deleteObjects:[cls allObjectsInRealm:self.rlmRealm]];
break;
case realmDelTypeFirst:
[self.rlmRealm deleteObject:[cls allObjectsInRealm:self.rlmRealm].firstObject];
break;
case realmDelTypeLast:
[self.rlmRealm deleteObject:[cls allObjectsInRealm:self.rlmRealm].lastObject];
break;
case realmDelTypeOther:
[self.rlmRealm deleteObjects:results];
break;
default:
break;
}
// 提交事務(wù)
return [self.rlmRealm commitWriteTransaction:&error];
}
// 更新數(shù)據(jù)
-
(BOOL)realmsUpdateData:(NSString *)object theCondition:(NSString *)condition property:(NSDictionary *)dict{
Class cls = NSClassFromString(object);
if (cls == nil) {
return NO;
}RLMResults *results = [self realmsselectData:object theCondition:condition];
if (!results.count) {
return YES;
}if (dict == nil) {
return NO;
}// 檢查屬性
if (![self CheckPropertys:object propertyDict:dict]) {
return NO;
}NSError *error = nil;
[self.rlmRealm beginWriteTransaction];//將每條數(shù)據(jù)的每個(gè) 屬性設(shè)置為對(duì)應(yīng)的值
for (NSString *updateKey in dict.allKeys) {
[results setValue:dict[updateKey] forKeyPath:updateKey];
}
// 如果沒(méi)有值,就新插入一條數(shù)據(jù)
//[cls createOrUpdateInRealm:self.rlmRealm withValue:dict];return [self.rlmRealm commitWriteTransaction:&error];
}
// 檢查該類中是否有該屬性
-
(BOOL)CheckPropertys:(NSString *)object propertyDict:(NSDictionary *)dict{
Class cls = NSClassFromString(object);
// 屬性字符串?dāng)?shù)組
NSMutableArray *clspropertys = [NSMutableArray array];unsigned pCount;
objc_property_t *properties = class_copyPropertyList(cls, &pCount);//屬性數(shù)組for(int i = 0; i < pCount; i++){
objc_property_t property = properties[i];
NSString *str =[NSString stringWithFormat:@"%s", property_getName(property)];
[clspropertys addObject:str];
//NSLog(@"propertyName:%s",property_getName(property));
//NSLog(@"propertyAttributes:%s",property_getAttributes(property));
}NSArray *keys = dict.allKeys;
for (NSString *dictkey in keys) {
if ([clspropertys containsObject:dictkey]) {
NSLog(@"This class does contain attributes.:%@",dictkey);
}else {
NSLog(@"This class does not contain attributes.:%@",dictkey);
return NO;
}
}
return YES;
}
代碼調(diào)用
RLMResults *results = [BankInfo objectsInRealm:self.rlmRealm where:@"bank_accno = '6228481234567891235' "];
NSLog(@"results = %@", results);
NSLog(@"banklistselect = %@", [BankInfo allObjectsInRealm:self.rlmRealm]);
//[self realmsDeleteData:NSStringFromClass([BankInfo class]) theCondition:@"bank_accno = '6228481234567891235' or bank_accno = '6228481234567891242' " type:realmDelTypeOther];
//NSLog(@"banklistDelete = %@", [BankInfo allObjectsInRealm:self.rlmRealm]);
[self realmsUpdateData:NSStringFromClass([BankInfo class]) theCondition:nil property:@{@"status":@"6", @"bank_accnoalias":@"123"}];
NSLog(@"banklistUpdate = %@", [BankInfo allObjectsInRealm:self.rlmRealm]);
[self.rlmRealm beginWriteTransaction];
// 先刪除數(shù)據(jù)
[self.rlmRealm deleteObjects:[Person allObjects]];
Person *p = [[Person alloc] init];
p.name = @"張三";
[p.banks addObjects:[BankInfo allObjectsInRealm:self.rlmRealm]];
[self.rlmRealm addObject:p];
[self.rlmRealm commitWriteTransaction:nil];
+ Realm中所有有關(guān)數(shù)據(jù)庫(kù)的操作都是一個(gè)事務(wù)段标。
即所有的代碼都需要去被包含在beginWriteTransaction和commitWriteTransaction之間涯冠。
+ Realm查詢結(jié)果,Realm將會(huì)返回包含 RLMObject 集合的RLMResults實(shí)例逼庞。RLMResults 的表現(xiàn)和 NSArray 十分相似蛇更,并且包含在 RLMResults 中的對(duì)象能夠通過(guò)索引下標(biāo)進(jìn)行訪問(wèn)。和 NSArray 不同往堡,RLMResults 需要指定類型械荷,并且其當(dāng)中只能包含RLMObject 子類類型的屬性共耍。
所有的查詢(包括查詢和屬性訪問(wèn))在 Realm 中都是延遲加載的虑灰,只有當(dāng)屬性被訪問(wèn)時(shí),才能夠讀取相應(yīng)的數(shù)據(jù)痹兜。
+ Realm 支持許多常見(jiàn)的斷言:
比較操作數(shù)(comparison operand)可以是屬性名稱或者某個(gè)常量穆咐,但至少有一個(gè)操作數(shù)必須是屬性名稱;
比較操作符 ==、<=对湃、<崖叫、>=、>拍柒、!=, 以及 BETWEEN 支持 int, long, long long, float, double, 以及 NSDate 屬性類型的比較心傀,比如說(shuō) age == 45;
相等比較 ==以及!=拆讯,比如說(shuō)[Employee objectsWhere:@"company == %@", company]
比較操作符 == and != 支持布爾屬性脂男;
對(duì)于 NSString 和 NSData 屬性來(lái)說(shuō),我們支持 ==种呐、!=宰翅、BEGINSWITH、CONTAINS 以及 ENDSWITH 操作符爽室,比如說(shuō) name CONTAINS ‘Ja’汁讼;
字符串支持忽略大小寫的比較方式,比如說(shuō) name CONTAINS[c] ‘Ja’ 阔墩,注意到其中字符的大小寫將被忽略嘿架;
Realm 支持以下復(fù)合操作符:“AND”、“OR” 以及 “NOT”啸箫。比如說(shuō) name BEGINSWITH ‘J’ AND age >= 32眶明;
包含操作符 IN,比如說(shuō) name IN {‘Lisa’, ‘Spike’, ‘Hachi’}筐高;
==搜囱、!=支持與 nil 比較,比如說(shuō) [Company objectsWhere:@"ceo == nil"]柑土。注意到這只適用于有關(guān)系的對(duì)象蜀肘,這里 ceo 是 Company 模型的一個(gè)屬性。
通過(guò) ==, != 進(jìn)行空值比較稽屏,比如說(shuō) [Company objectsWhere:@"ceo == nil"]扮宠; 注意,Realm 將 nil 視為一個(gè)特殊的值而不是“缺失值”狐榔,不像 SQL 那樣 nil 等于自身坛增。
ANY 比較,比如說(shuō) ANY student.age < 21
RLMArray 以及 RLMResults 屬性支持集合表達(dá)式:@count薄腻、@min收捣、@max、@sum 以及 @avg庵楷,例如 [Company objectsWhere:@"employees.@count > 5"] 用以尋找所有超過(guò) 5 名雇員的公司罢艾。
支持子查詢楣颠,不過(guò)有限制:
@count 是唯一能應(yīng)用在 SUBQUERY 表達(dá)式中的操作符
SUBQUERY(…).@count 表達(dá)式必須與常量進(jìn)行比較
####其他
在測(cè)試的過(guò)程中,如果模型類的屬性進(jìn)行了添加或者刪除操作咐蚯,重新執(zhí)行會(huì)報(bào)錯(cuò)童漩,重新刪除app的數(shù)據(jù)即可。
最后執(zhí)行結(jié)果
![](http://upload-images.jianshu.io/upload_images/1101711-b0aee6127ac7a8d7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](http://upload-images.jianshu.io/upload_images/1101711-09c7102c120a9b79.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
####參考地址
[官網(wǎng)地址](https://realm.io)
[參考地址1](http://www.cocoachina.com/ios/20150505/11756.html)