Realm数据库详解

2016-03-15  本文已影响1055人  叫我小詺

Realm,为移动设备而生。替代 SQLite 和 Core Data。

官方中文文档:官方文档

以上是官方文档,大家看过后有个大体了解。

说一下我对Realm的认识。

首先它的API调用特别舒服,不繁琐。

还有一个好处就是省心,不用像CoreData那样复杂的管理。也不用写SQL语句。总之,简单!

高效,开发中应用测试时,无论是那种操作,都是秒操作。所以性能不是问题。

下面是具体操作(看过官方文档,有一定认识后在操作)

我只是复述一下我对官方文档的理解,以及我集成Realm的过程操作

从这里开始(集成过程)

Realm是开源的~,下载方式静态库,以及官方Demo。下载 Realm OC版(Swift版和OC版是不能共存的):下载OC版Realm

准备工作

使用 Realm 构建应用的基本要求:iOS >= 7, OS X >= 10.9 并且支持 WatchKit。;

需要使用 Xcode 6.4 或者以后的版本;

程序支持Objective‑C, Swift 1.2 & Swift 2.x。

安装 (这里有好多可选的方式,看大家喜欢,我用的是静态库)

1.动态框架

2.CocoaPod

3.Carthage

4.静态框架(因为其他的需要些脚本)

Realm浏览器/数据库管理器

官方提供了一个名为Realm Browser的Mac应用,用来进行Realm数据的读取和编辑。(好用,但是每次编译写入新数据的时候,之前打开的会闪退)

Xcode 插件

怎么安装就不赘述了,最开始的时候我会用,后来用多了,就自己手动建模型类了。

API手册

能查询Realm的完整版API手册,里面包含了所有类和方法等信息。

示例

官方Demo里有(好多,而且是英文不是很懂)

数据模型(Model)

Realm数据模型是基于标准 Objective‑C 类来进行定义的,使用属性来完成模型的具体定义。

通过简单的继承RLMObject或者一个已经存在的模型类,您就可以创建一个新的 Realm 数据模型对象。

Realm模型对象在形式上基本上与其他 Objective‑C 对象相同 - 您可以给它们添加您自己的方法(method)和协议(protocol),和在其他对象中使用类似。

主要的限制是某个对象只能在其被创建的那个线程中使用, 并且您无法访问任何存储属性的实例变量(ivar)。

如果您安装了我们的Xcode插件,那么可在”New File…“对话框中会有一个很漂亮的模板,可用来创建接口(interface)和执行(implementation)文件。

您只需要为对象的类型列表添加目标类型的属性,或者RLMArray,就可以创建数据关系(relationship)和嵌套数据结构(nested data structure)。

我就不用官方文档里的类说明了,以下就是实际项目(gitDemo)中类的创建以及使用

导入项目中的DataStore文件夹

拖进来之后(确保拖入时勾选了 Copy items if needed ),可能会报错,查看报错信息,(一般是缺少libc++.tbd)

建模型的基类

我将常用的数据库操作已经做了封装,在Store文件夹下是Realm数据库的管理类,同时每个模型类都需要主键,所以应该抽象出父类来持有primaryKey和realmManager是有必要的。

模型类需要跟官方文档里描述一致需要继承RLMObject类RLM_ARRAY_TYPE(BasicRealm)定义一个RLMArray类型(不太明白的可以看一下官方源码)

#import <Realm/Realm.h>

#import"RLMObject+JSON.h"

#import"XMRealmStoreManager.h"

@interfaceBasicRealm :RLMObject

/**

*本地数据库入库的主键ID

*/

@property(nonatomic,copy)NSString*hostID;

/**

*  realm数据管理

*

*  @return realm数据管理

*/

+(XMRealmStoreManager*)realmManager;

-(XMRealmStoreManager*)realmManager;

@end
// This protocol enables typed collections. i.e.:

// RLMArray

RLM_ARRAY_TYPE(BasicRealm)

@interfaceBasicModel :NSObject

@property(nonatomic,copy)NSString*hostID;

@end

.m文件的具体方法请从项目中查看

建数据模型类

现在就可以根据项目需求建立明确的模型类,模型类需要继承上述的基类BasicRealm。

假如现在的需求是Cell的标题下有三张图片(大家自行脑补一下UI),那么我们需要标题属性,以及一个图片链接数组(Realm中不能用NSArray,需要用RLMArray)属性声明如下

#import"BasicModel.h"

RLM_ARRAY_TYPE(ImageRealm)//定义一个RLMArray类型

@interfaceDataRealm :BasicRealm

@property(nonatomic,copy)NSString*title;

@property(nonatomic,strong)RLMArray * image_url;

@end
@interfaceImageRealm :BasicRealm

@property(nonatomic,copy)NSString*image;

@end

.m中需要重写两个方法

+ (NSDictionary*)JSONInboundMappingDictionary(入库的keyPath对应模型的keyPath)

+ (NSDictionary*)JSONOutboundMappingDictionary(出库的keyPath对应模型的keyPath)
两个方法一般内容都相同,一般我们写的模型类都是基于服务器返回数据的KeyPath作为我们数据类的属性名。但当服务器返回的数据(比如服务器数据库的主键是id,当然你也可以跟服务端开发商量一下提前做一下key的更改,毕竟好兄弟~)有一些OC的关键词比如id这样的话我们就需要将入(出)库的keyPath对应模型的keyPath做一下映射的更改

@implementationDataRealm

+ (NSDictionary*)JSONInboundMappingDictionary {

return@{

@"hostID":@"hostID",

@"image_url":@"image_url",

@"title":@"title",

};

}

+ (NSDictionary*)JSONOutboundMappingDictionary {

return@{

@"hostID":@"hostID",

@"image_url":@"image_url",

@"title":@"title",

};

}

@end
@implementationImageRealm

+ (NSDictionary*)JSONInboundMappingDictionary {

return@{

@"hostID":@"hostID",

@"image":@"image",

};

}

+ (NSDictionary*)JSONOutboundMappingDictionary {

return@{

@"hostID":@"hostID",

@"image":@"image",

};

}

@end

Realm数据模型类的使用

用Realm管理类调用数据的增删改差

//增or改

-(void)add

{

[[DataRealmrealmManager]writeObjectsWithObjectsBlock:^id(XMRealmOperation*operation,RLMRealm*realm) {

//在这返回一个id对象可以是一个包含多个数据库模型的数组,也可以是单个数据库模型对象可以调用Real自己的解析字典方法,也可以用封装好的方法(根据服务器返回的数据类型)

return[DataRealmcreateOrUpdateInRealm:realmwithJSONDictionary:@{@"hostID":@"1",@"title":@"好好学习天天向上",@"image_url":@[@{@"hostID":@"1",@"image":@"http://image1"},@{@"hostID":@"2",@"image":@"http://image2"},@{@"hostID":@"3",@"image":@"http://image3"}]}];

//        return [DataRealm createOrUpdateInRealm:realm withJSONArray:@[]];

}completion:^(XMRealmStoreManager*store,XMRealmOperation*operation,RLMRealm*realm) {

//事务完成后回调

}];

}
//删

-(void)delete{

[[DataRealmrealmManager]deleteObjectsWithObjectsBlock:^id(XMRealmOperation*operation,RLMRealm*realm) {

//可以根据sql语句查找删除

return[DataRealmobjectsWhere:@""];

//也可以根据主键获得

return[DataRealmobjectForPrimaryKey:@"1"];

}completion:^(XMRealmStoreManager*store,XMRealmOperation*operation,RLMRealm*realm) {

//事务完成回调

}];

}
//查

-(void)search

{

[[DataRealmrealmManager]fetchObjectsWithObjectsBlock:^id(XMRealmOperation*operation,RLMRealm*realm) {

//可以根据sql语句查找删除

return[DataRealmobjectsWhere:@""];

//也可以根据主键获得

return[DataRealmobjectForPrimaryKey:@"1"];

}completion:^(XMRealmStoreManager*store,XMRealmOperation*operation,RLMRealm*realm,RLMResults*results,NSString*primaryKey,NSMutableArray*models) {

//事务完成回调获得查询内容更新UI

}];

}

后语:

我建议大家将数据分为两种类,一种是数据库类,一种是平常我们不做数据存储的类(我在Demo (由于git文件大小限制不能上传Realm.framework,请大家自行拖入)中是这样操作的)。这样做的好处是分开来易于管理,那些属性内容需要入库就在数据库类中声明,不需要的但是我们UI展示上需要的在单独的数据类中。这样数据库中就不需要冗余的key(当然也可以通过.m的两种方法来控制入库的keyPath)这样做还有一个不算原因的原因,这样做可以用一些字典转模型的解析类框架(比如MJ,YYModel等)。总是这项看个人喜好吧。

上一篇下一篇

猜你喜欢

热点阅读