移动开发数据库篇 之 SwiftRealm(上)

移动开发数据库篇 之 SwiftRealm(上)


@author fharmony Email Weibo or Github


Realm is a mobile database
hundreds of millions of people rely on .

1. 为什么要使用SwiftRealm?

新型数据库,同类型三方库有CoreDataSQLite
特点:简单、快、文档规范、免费
需要:iOS 8.0+(指的是Swift版本)

需要继承Object,具有一定程度的侵入性。和AVOS Object类似。但是需要注意的是,如果使用的话realm是存储在本地的数据,和AVOS Object存储在云端的数据作用不一样。

快速集成

使用Cocoapods快速集成,请参考这个文章
podfile内容:

platform :ios,'8.0'
use_frameworks!
target '<#你的TargetName#>' do
pod 'RealmSwift'
end

2. 数据模型 - 关系

数据模型的创建

可以使用Realm提供的Realm Model创建,文件需要满足:

  • 指定数据类型或者是List类型
  • 一定需要初始化

数据模型的关系

  • 一对一关系 可以为空
  • 一对多关系 通过List完成,提供了List类来作为列表
  • 反向关系 可以通过一个特定的属性获取和给定对象有关系的所有对象。即「具有XX属性的那些对象」

数据类型:

常用类型:Bool\Double\Float\String\NSDate\NSData\Int32\Object
可选与不可选类型

* 对于基本类型来说:
let style = RealmOptional<Int32>() --> 可选值
dynamic var style = 32 --> 不可选值

* 对对象类型来说
let var value:Stirng? = nil --> 可选值
dynamic var value = ""

为什么使用dynamic?因为realm工作基于OC运行时。
为什么不使用计算属性?计算属性将不会被存储到realm里面

索引属性

重写Object.indexedProperties()添加索引属性,支持用字符串、整数、布尔值、NSDate作为索引,有利于提高检索效率。

主键

重写Object.primaryKey()添加主键,主键不可修改而且能让查询更加高效。注意数据库的主键是条目的唯一标示,如果有两条主键相同的条目,那么后来的条目会更新前一个条目的数据。

忽略属性

重写 Object.ignoredProperties() 可以忽略 Realm 存储数据模型的某个属性。

3.对数据库的操作

对象存储

对对象存储的更改需要通过写入事务write闭包完成。
如果您想要在多个线程中共享对象,或者在应用重启后重复使用对象,那么您必须将其存储到Realm数据库中——这个操作必须在写入事务中完成。
写入事务可能会失败,所以需要添加throws标记处理异常

  • 增删改
let realm = try! Realm()//建立realm数据库
try! realm.write{
    realm.add(object)//插入新对象
    object.name = "new value"//更新数值
    realm.add(object,update:true)//对已经存在的值进行更新操作,或者是对不存在的值进行写入,是否存在依据的是主键
    realm.delete(object)//删除对象

}

* 查  

返回Results实例,查询得到的是数据库里面的数据,在写入操作的时候可以修改数据库的数据。您可以将 Results 存储为一个属性,这样就无需在每次访问前都要刷新数据以确保数据最新了。realm的查询允许链式查询。

let dogs = realm.Objects(Dog)
let tanDogs = realm.Objects(Dog).filter("NSPredicate断言")
  • 排序
    根据某个属性进行排序
let sortedDogs = realm.objects(Dog).filter("color = '棕黄色' AND name BEGINSWITH 'B'").sorted("color")

创建对象

var myDog = Dog()
和swift新建对象的方法一致

创建数据库

通过调用 Realm()会在应用文件夹下的一个名为“default.realm”的文件,realm.path来获取realm数据库地址,可以使用Realm Browser进行查看

配置realm

通过Realm.Configuration您可以配置诸如 Realm 文件在何处存储之类的信息。苹果推荐<Application_Home>/Library/Caches目录下,
在生成 Realm 文件的代码处,您需要结尾对文件进行压缩拷贝(参见 Realm().writeCopyToPath(_:encryptionKey:))。 这有助于减少 Realm 的文件体积,让您发布的应用体积更小;

删除数据库

大多数文件可以通过removeItemAtPath删除,但是您必须要采取额外的操作,来确保没有任何活跃的 Realm 对象在删除过程中访问数据库。Realm 实例将会在它们的整个生命周期中,持有对数据库的连接。限制 Realm 实例生命周期的方法就是使用 autorelease pool 将其使用操作包含在其中。所有 path 指向您想要删除的 Realm 文件的 Realm 实例,都必须要在删除操作执行前被释放掉。

4. 多线程

Realm 通过确保每个线程始终拥有 Realm 的一个快照,以便让并发运行变得十分轻松。您唯一需要注意的一件事情就是不能让多个线程都持有同一个 Realm 对象的 实例 。如果定期刷新 Realm 失败的话,就可能会导致某些事务的版本变为“锁定(pinned)”状态,阻止 Realm 重用该版本的硬盘空间,从而导致文件尺寸变大。
不支持 跨线程共享Realm 实例。 Realm 实例要访问相同的 Realm 文件还必须使用相同的 Realm.Configuration。
当你同时进行多个写操作的时候,他们会相互阻塞,阻塞住他们所运行的线程。因此您必须要为每一个您想要执行读取或者写入操作的线程或者dispatch队列创建一个 Realm 实例。所以应当考虑在 UI 之外的线程中来进行操作。另外需要注意的是,在进行写事务的时候,读操作并不会造成阻塞。这非常有用,尤其是当你在后台进行写操作的时候,用户可能会在不同界面切换,而这时候可以进行读操作
Realm 对象在每个线程中都应该只被创建一次,因为它不是线程安全的,不能在不同的线程中共享。如果你想要在另一个线程中执行写操作,那么就需要创建一个新的 Realm 对象。
建议你使用常用的,也是最有效的方案, 将所有写入放到一个单独的进程中。

5. 其他

通知

通过调用 addNotificationBlock 方法进行通知注册后,无论哪个 Realm, Results 或者 List 对象更新,都可以得到通知。Results 以及 List 实例在注册的时候,会使用初始的集合来调用闭包,然后当每次写事务对集合或者包含在其中的任何事物进行改变之后,会再次调用一遍此闭包。

加密

  • 在iOS平台中,通过使用 NSFileProtection API 就可以花费极小的代价完成 Realm 的文件加密。
  • 使用realm官方的加密方法:
// 产生随机密钥
let key = NSMutableData(length: 64)!
SecRandomCopyBytes(kSecRandomDefault, key.length,
    UnsafeMutablePointer<UInt8>(key.mutableBytes))

// 打开加密文件
let config = Realm.Configuration(encryptionKey: key)
do {
  let realm = try Realm(configuration: config)
  // 和往常一样使用 Realm 即可
  let dogs = realm.objects(Dog).filter("name contains 'Fido'")
} catch let error as NSError {
  // 如果密钥错误,`error` 会提示数据库不可访问
  fatalError("Error opening realm: \(error)")
}

参考资料

Realm Swift官方文档


                                —— 念念不忘,必有回响

@author fharmony Email Weibo or Github

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容