 
        由于最近公司需要将项目用
Swift改写,项目中需要大量使用数据库,之前OC使用的是Core Data,Core Data使用起来确实十分的繁琐,故决定在Swift中弃用,改用Realm数据库,下面将使用方法记录下来方便以后查看。
Realm 的优点
Realm 不是基于 Core Data,也不是基于 SQLite 封装构建的。它有自己的数据库存储引擎,下面说一下 Realm 的一些优点。
- 跨平台: 现在很多应用都是要兼顾 - iOS和- Android两个平台同时开发。如果两个平台都能使用相同的数据库,那就不用考虑内部数据的架构不同,使用- Realm提供的- API,可以使数据持久化层在两个平台上无差异化的转换。代码可以使用- Swift、- Objective-C以及- Java语言来编写。
- 简单易用: - Core Data和- SQLite冗余、繁杂的知识和代码足以吓退绝大多数刚入门的开发者,而换用- Realm,则可以极大地减少学习成本,立即学会本地化存储的方法。大部分常用的功能(比如插入、查询等)都可以用一行简单的代码轻松完成,毫不吹嘘的说,把官方最新文档完整看一遍,就完全可以上手开发了,这是 中文官方文档地址。
- 可视化: - Realm还提供了一个轻量级的数据库查看工具,在- Mac Appstore可以下载- Realm Browser这个工具,开发者可以查看数据库当中的内容,执行简单的插入和删除数据的操作。

Realm Swift 的安装
这是 Realm 的 GitHub 地址 ,其他方法我就不说了,我是用 CocoaPods 方式安装的,所以就只说 CocoaPods 的安装方法了。
- 运行 - pod repo update,以确保- CocoaPods能够获取到- Realm的最新版本。
- 在你的 - Podfile中,添加- use_frameworks!和- pod 'RealmSwift'到你的主要和测试目标。
- 如果你使用的是 - Xcode 8,那么将下面代码复制到你的- Podfile底部,以便在必要的时候更新- Swift的版本。
| post_install do |installer| | 
- 在终端运行 - pod install。
- 采用 - CocoaPods生成的- .xcworkspace来运行工程。
- 在需要使用 - Realm Swift的地方加入- import RealmSwift。
Realm Browser 的使用
先说一下 Realm Browser 这个数据库查看工具的使用方法。
1. 模拟器调试
- 如果是使用模拟器进行调试,首先通过以下代码打印出 Realm数据库地址。
| let realm = try! Realm() | 
- 然后打开 Finder按下command + shift + G跳转到对应路径下,用Realm Browser打开对应的.realm文件就可以看到数据了。

2. 真机调试
- 如果是真机调试的话,打开 Xcode,选择菜单Window下的Devices。

- 选择对应的设备与项目,点击 Download Container。

- 导出 xcappdata文件后,显示包内容,进到AppData下的Documents,使用Realm Browser打开.realm文件即可。
Realm Swift 的使用
1. 配置 Realm 数据库
- 将以下代码写在 AppDelegate的didFinishLaunchingWithOptions方法中,这个方法主要用于数据模型属性增加或删除时的数据迁移,每次模型属性变化时,将schemaVersion加1即可,Realm会自行检测新增和需要移除的属性,然后自动更新硬盘上的数据库架构,移除属性的数据将会被删除。
| /* Realm 数据库配置,用于数据库的迭代更新 */ | 
- 如果属性改变后,想要保留原来已存在的数据来更新新的属性值,在属性变化后将 schemaVersion加1,并将config改为如下,其余不变。
| let config = Realm.Configuration(schemaVersion: schemaVersion, migrationBlock: { migration, oldSchemaVersion in | 
- 如果是只是属性重命名,想保留原来已经存在的数据,重命名以后将 schemaVersion加1,并将config改为如下,其余不变,并且重命名操作应该在调用上面enumerateObjects(ofType: _:)之外完成。
| let config = Realm.Configuration(schemaVersion: schemaVersion, migrationBlock: { migration, oldSchemaVersion in | 
2. Model 数据模型
Realm 数据模型是基于标准 Swift 类来进行定义的,使用属性来完成模型的具体定义,Realm 模型对象在形式上基本上与其他 Swift 对象相同,你可以给它们添加您自己的方法和协议,和在其他对象中使用类似。
Realm 支持的属性类
Realm 支持这几种属性类型:Bool、Int8、Int16、Int32、Int64、Double、Float、String、NSDate 以及 NSData ,下面的表格提供了关于声明模型属性的简易参考。
| 类型 | 非可选值形式 | 可选值形式 | 
|---|---|---|
| Bool | dynamic var value = false | let value = RealmOptional<Bool>() | 
| Int | dynamic var value = 0 | let value = RealmOptional<Int>() | 
| Float | dynamic var value: Float = 0.0 | let value = RealmOptional<Float>() | 
| Double | dynamic var value: Double = 0.0 | let value = RealmOptional<Double>() | 
| String | dynamic var value = "" | dynamic var value: String? = nil | 
| Data | dynamic var value = NSData() | dynamic var value: NSData? = nil | 
| Date | dynamic var value = NSDate() | dynamic var value: NSDate? = nil | 
| Object | 必须是可选值 | dynamic var value: Class? | 
| List | let value = List<Class>() | 必须是非可选值 | 
| LinkingObjects | let value = LinkingObjects(fromType: Class.self, property: "property") | 必须是非可选值 | 
Model 数据模型创建
下面以 Dog 和 Person 为例,通过简单的继承 Object 或者一个已经存在的模型类,你就可以创建一个新的 Realm 数据模型对象。
普通的数据模型
| /// 狗狗的数据模型 | 
关系绑定
| /// 狗狗的数据模型 | 
反向关系
如果对多关系属性 Person.dogs 链接了一个 Dog 实例,而这个实例的对一关系属性 Dog.owner 又链接到了对应的这个 Person 实例,那么实际上这些链接仍然是互相独立的。
为 Person 实例的 dogs 属性添加一个新的 Dog 实例,并不会将这个 Dog 实例的 owner 属性自动设置为该 Person。
但是由于手动同步双向关系会很容易出错,并且这个操作还非常得复杂、冗余,因此 Realm 提供了 链接对象 (linking objects) 属性来表示这些反向关系。
| /// 狗狗的数据模型 | 
索引属性(Indexed Properties)
重写 Object.indexedProperties() 方法可以为数据模型中需要添加索引的属性建立索引。Realm 支持字符串、整数、布尔值 以及 NSDate 属性作为索引。对属性进行索引可以减少插入操作的性能耗费,加快比较检索的速度(比如说 = 以及 IN 操作符)
| /// 狗狗的数据模型 | 
主键(Primary Keys)
重写 Object.primaryKey() 可以设置模型的主键。声明主键之后,对象将允许进行查询,并且更新速度更加高效,而这也会要求每个对象保持唯一性。 一旦带有主键的对象被添加到 Realm 之后,该对象的主键将不可修改。
Realm 可以将 Int 和 String 类型的属性设为主键,但是不支持自增长属性,所以只能自己给主键生成一个唯一的标识,可以使用 UUID().uuidString 方法生成唯一主键。
| /// 狗狗的数据模型 | 
忽略属性(Ignored Properties)
重写 Object.ignoredProperties() 可以防止 Realm 存储数据模型的某个属性。Realm 将不会干涉这些属性的常规操作,它们将由成员变量提供支持,并且您能够轻易重写它们的 setter 和 getter 。
| /// 狗狗的数据模型 | 
3. 创建数据模型对象
- 可以用多种方法创建一个新的对象:
| /* (1) 创建一个狗狗对象,然后设置其属性 */ | 
- 即使是数组以及字典的多重嵌套,Realm也能够轻松完成对象的创建。注意List只能够包含Object类型,不能包含诸如String之类的基础类型。
| /* 这里我们就可以使用已存在的狗狗对象来完成初始化 */ | 
4. 数据库操作(增删改查)
任何操作都需要获取 Realm 实例,每个线程只需要使用一次即可。
| /* 获取默认的 Realm 实例,每个线程只需要使用一次即可 */ | 
增加数据
| /* 创建一个 Dog 对象 */ | 
删除数据
| // let dog = ... 存储在 Realm 中的 Dog 对象 | 
修改数据
- 内容直接更新: 在事务中直接修改某一条数据。
| // let dog = ... 存储在 Realm 中的 Dog 对象 | 
- ** 通过主键更新: ** 如果你的数据模型中设置了主键的话,那么你可以使用 Realm().add(_:update:)来更新数据,如果数据不存在时会自动插入新的数据。
| // let dog = ... 存储在 Realm 中的 Dog 对象(有主键) | 
- 键值编码: Object、Result以及List都遵守 键值编码(Key-Value Coding) 机制。 当你在运行时才能决定哪个属性需要更新的时候,这个方法是最有用的。将KVC应用在集合当中是大量更新对象的极佳方式,这样就可以不用经常遍历集合,为每个项目创建一个访问器了。
| // let dogs = ... 存储在 Realm 中的多个 Dog 对象 | 
查询数据
- 普通查询: 查询数据库中某张表的所有数据。
| /* 从数据库中查询所有狗狗 */ | 
- 主键查询: 根据 主键查询某张表的某条数据,模型必须包含主键,否则会崩溃。
| /* 从数据库中查询主键为 1 的狗狗 */ | 
- 条件查询: 根据 断言字符串或者NSPredicate 谓词查询某张表中的符合条件数据。
| /* 根据断言字符串从数据库查询 name 为 张三 的狗狗 */ | 
- 排序查询: 将查询结果进行排序,可以和条件查询配合使用。
| /* 将查询到的狗狗根据名字升序进行排序 */ | 
想要了解更多可以查看 中文官方文档地址 ,有不足之处之后会补充,
OC版本的话可以看这篇文章:Realm数据库 从入门到“放弃” ,写的非常详细,也参考了不少这篇文章的内容。
 
         
        