Realm入门
来源:互联网 发布:金石工程计价软件 编辑:程序博客网 时间:2024/06/05 04:41
官网,在官网上查看文档教程。为查看数据可安装Realm Browser
内容来自raywenderlich
Realm入门
这里使用的是Realm
并不是最新的版本,Cocoapod如下:
platform :ios, ‘9.0’use_frameworks!target 'Todoify' do pod 'RealmSwift', '~> 0.98'end
通过简单的继承 Object
或者一个已经存在的模型类,您就可以创建一个新的 Realm
数据模型对象
属性的类型
绝大多数的属性都需要一个前缀dynamic
,让Realm
把属性与底层的C++
映射起来
主键(Primary Keys):重写 Object.primaryKey()
可以设置模型的主键。声明主键之后,对象将允许进行查询,并且更新速度更加高效,而这也会要求每个对象保持唯一性。 一旦带有主键的对象被添加到 Realm 之后,该对象的主键将不可修改。
override class func primaryKey() -> String? { return "id" }
索引属性(Indexed Properties):重写 Object.indexedProperties()
方法可以为数据模型中需要添加索引的属性建立索引。对属性进行索引可以减少插入操作的性能耗费,加快比较检索的速度(比如说 = 以及 IN 操作符)
override class func indexedProperties() -> [String] { return ["title"] }
忽略属性(Ignored Properties):重写 Object.ignoredProperties()
可以防止 Realm 存储数据模型的某个属性。
override class func ignoredProperties() -> [String] { return ["tmpID"] }
基本用法
以实现一个待办事项的app为例,使用realm来保存待办的事项,所以先创建一个Task
类,Task
类继承自Object
Task
任务类
import Foundationimport RealmSwiftclass Task: Object { dynamic var taskId = NSUUID().UUIDString dynamic var title = "" dynamic var done = false dynamic var created = NSDate() dynamic var priority = 0 convenience init(title: String, priority: Int) { self.init() self.title = title self.priority = priority } override class func primaryKey() -> String? { return "taskId" } override class func indexedProperties() -> [String] { return ["done"] }}extension Task { var priorityText: String { return priority > 0 ? "High" : "Default" } var priorityColor: UIColor { return priority > 0 ? UIColor.redColor() : UIColor.blueColor() }}
Realm不会尝试初始化任何没有setter的属性 - 包括任何只读和动态属性。 extension
中的priorityText
属性没有setter方法,所以Realm不会试图将其在disc上或内存中保存下来
在保存或者查询数据之前,要获取Realm的一个引用,最简单的方式是获取默认的Realm的实例,获取的应用的默认的realm,位于沙盒的Documents
文件夹中
let realm = try! Realm()
如果想让Realm在app的另外的位置,可指定location的URL。或者你做更多的配置,可创建Realm.Configuration
let realm = try! Realm(fileURL: myUrl)let myConfig = Realm.Configuration(fileURL: myUrl)let realm = try! Realm(configuration: myConfig)
保存
例如,保存一个待办事项Task
let realm = try! Realm() let task = Task(title: taskTitle.text!, priority: taskPrio.selectedSegmentIndex) // 通过事务将数据添加到 Realm 中 try! realm.write({ realm.add(task) })
查询
查询操作,Realm将会返回包含Object
集合的Results
实例。 Results
的特点
Results are typed
例如获取类型为Dog
的数据或者获取类型为Person
的数据the data is dynamic (zero copy)
表示Realm不会从disc复制任何数据到memory,总是直接从disc获取数据,所以获取的总是最新的数据。从disc读取数据并会不会占用内存queryable and sortable
可查询,可排序- 与
NSPredicate
相似的语法
例如,查询所有的Task
先定义一个变量来保存tasks
,类型为Results<Task>
var tasks: Results<Task>!
查询所有Task
let realm = try! Realm() tasks = realm.objects(Task)
更新
Realm 提供了一系列用以更新数据的方式,这些方式都有着各自所适应的情景
内容直接更新
在写入事务中通过设置某个对象的属性从而完成对象的更新操作
// 在一个事务中更新对象try! realm.write { author.name = "托马斯·品钦"}
通过主键更新
如果您的数据模型中设置了主键的话,那么您可以使用Realm().add(_:update:)
来更新对象,或者当对象不存在时插入新的对象。
// 创建一个带有主键的“书籍”对象,作为事先存储的书籍let cheeseBook = Book()cheeseBook.title = "奶酪食谱"cheeseBook.price = 9000cheeseBook.id = 1// 通过 id = 1 更新该书籍try! realm.write { realm.add(cheeseBook, update: true)}
如果主键 id 为1的 Book 对象已经存在于数据库当中了,那么对象就会简单地进行更新。而如果不在数据库中存在的话,那么这个操作将会创建一个新的 Book 对象并添加到数据库当中。
您同时通过传递您想要更新值的集合,从而更新带有主键的某个对象的部分值,比如说如下所示:
// 假设带有主键值 `1` 的“书籍”对象已经存在try! realm.write { realm.create(Book.self, value: ["id": 1, "price": 9000.0], update: true)// 这本书的`title`属性不会被改变}
教程的这个例子是先通过taskId
主键获取到task
,然后通过内容直接更新, 如下:
if let realm = try? Realm(), let id = taskId, let task = realm.objectForPrimaryKey(Task.self, key: id){ try! realm.write({ task.done = checked }) check.selected = task.done }
删除
通过在写入事务中将要删除的对象传递给 Realm().delete(_:)
方法
// 在事务中删除一个对象try! realm.write { realm.delete(cheeseBook)}
删除所有数据
// 从 Realm 中删除所有数据try! realm.write { realm.deleteAll()}
教程中的这个例子,删除待办事项,滑动cell删除
try! tasks.realm!.write({ let task = tasks[indexPath.row] self.tasks.realm?.delete(task) })
集合
在前面的例子中,获取到了全部的数据。但在大部分应用的场合,我们需要的并不是全部的数据,而是符合某些条件的特定数据,这就要用到过滤filter,对数据和可以应用sorter进行排序
本例中,使用filter来过滤出done == true
的数据,并且按照priority
和created
排序
请注意,sorted(byKeyPath:)
以及 sorted(byProperty:)
不支持将多个属性用作排序基准,如果要按多个属性进行排序的话,请使用 sorted(by:)
方法,然后向其中传递多个 SortDescriptor
对象。
func getTask(done: Bool) -> Results<Task>{ let realm = try! Realm() tasks = realm.objects(Task) if done { tasks = tasks.filter("done == true") } //return tasks.sorted("created", ascending: false) return tasks.sorted([ SortDescriptor(property: "priority", ascending: false), SortDescriptor(property: "created", ascending: false) ])}
Realm 集合
Results
类,表示从检索 中所返回的对象集合。List
类,表示模型中的对多关系。LinkingObjects
类,表示模型中的反向关系。
本例中,添加一个User
类,一个user可对应多个task,如下:
class User: Object { dynamic var name = "" //User对应的tasks let tasks = List<Task>() convenience init(name: String) { self.init() self.name = name }}
那么,在保存Task
的时候,可直接使用如下的形式:
let realm = try! Realm() let task = Task(title: taskTitle.text!, priority: taskPrio.selectedSegmentIndex) let user = users[taskUsers.selectedSegmentIndex] try! realm.write({ user.tasks.append(task) })
如上user.tasks.append(task)
,这样做数据不会重复
Realm 通知
Realm 支持对象级别的通知。您可以在特定的 Realm 对象上进行通知的注册,这样就可以在此对象被删除时、或者该对象所管理的属性值被修改时(同样也适用于当对象所管理的属性值被设置为既有值的时候),获取相应的通知。
changes有三种值:
.Initial(collection)
.Update(collection, deletes,inserts, updates)
.Error(error)
本例,在tasks上注册通知,使用的方式,官方文档中有详细的介绍
var subscription: NotificationToken?func notificationSubscription(tasks: Results<Task>) -> NotificationToken { return tasks.addNotificationBlock({ [weak self] (change: RealmCollectionChange<Results<Task>>) in self?.updateUI(change) })}func updateUI(change: RealmCollectionChange<Results<Task>>) { switch change { case .Initial(_): tableView.reloadData() case .Update(_, let deletions, let insertions, _): tableView.beginUpdates() tableView.insertRowsAtIndexPaths(insertions.map({NSIndexPath(forRow: $0, inSection: 0)}), withRowAnimation: .Automatic) tableView.deleteRowsAtIndexPaths(deletions.map({NSIndexPath(forRow: $0, inSection: 0)}), withRowAnimation: .Automatic) tableView.endUpdates() break case .Error(let error): print(error) }}
其它文章
- Realm数据库 从入门到“放弃”
- iOS中Realm数据库的基本用法
- Realm入门
- Realm快速入门攻略
- Shiro入门-自定义realm
- Realm简单入门(转载)
- Realm for Android 快速入门
- Realm 入门 简单实用方法
- Realm for Android 使用入门
- Realm for Android 使用入门
- React Native Realm安装 和 Realm入门理解
- realm
- Realm
- Realm
- realm
- Realm
- realm
- Realm
- Shiro入门10:自定义Realm进行授权
- Realm数据库学习之快速入门
- iOS 【令人头疼的 SDWebImage 缓存问题】
- Eclipse 在开发中使用到的快捷键
- 题目1011:最大连续子序列 九度OJ
- Java面试题全集(下)
- Jfinal 源码阅读方式
- Realm入门
- 利用反射机制创建实例化对象工厂
- jQuery $.extend()用法总结
- 微信蓝牙连接 总结
- cocos2D 1
- 移动端下拉刷新、上拉加载更多插件dropload的使用
- TensorsFlow学习笔记3----面向机器学习初学者的MNIST教程(MNIST For ML Beginners)
- 20个常用正则表达式,让你少写1000行代码
- KETTLE后台进程执行配置方式