Realm 数据库使用
Table of Contents(目录)
0. 项目描述
1. Realm模型
2. Realm数据库安装
3. 创建Model
4. 实现CreateRandomDatabase函数创建初始数据库
创建数据库、删除数据库
创建Model实例,修改Model实例,删除Model实例,增、删、改操作
查询Model,查询、排序、分页操作
5. 数据库结构更新,迁移
6. 数据绑定,数据更新通知,观察者模式
0. 项目描述
Realm练习:约车软件,提供4个页面
- Tab 1:列出所有当前可约行程
- Tab 2:列出所有当前用户参与的行程
- Tab 3:列出所有当前用户参与的留言
- Tab 4:系统设置页面
本文中只给出了Realm的用法
userName | 主键:用户名 |
mobilePhoneNumber |
手机号 |
portraitImage |
头像 |
qrcodeImage |
收款二维码 |
following |
外键 User:关注者列表 |
fans |
外键 User:粉丝列表 |
cars |
外键 Car:用户拥有的车辆列表 |
apps |
外键 Appointment:用户发布的所有行程 |
enrollapps |
外键 Appointment:用户参与的所有行程 |
sendmessages |
外键 Message:用户发送的所有信息 |
receivemessages |
外键 Message:用户接受的所有消息 |
brand |
车辆品牌 |
color | 车辆颜色 |
id | 车牌号 |
owner | 外键 User:车辆拥有者 |
createDate |
行程创建时间 |
beginDate |
行程开始时间 |
startLocal |
行程开始地点 |
endLocal |
行程结束地点 |
mobilePhoneNumber |
行程发布者手机号 |
customerNumber |
行程可预约人数 |
costPerCustomer |
行程每人单价 |
car |
外键 Car:行程所使用的的汽车 |
customer |
外键 User:行程中的所有乘客 |
owner |
外键 User:行程发布者 |
msg |
信息内容 |
createDate | 信息创建时间 |
sender | 外键 User:信息发送人 |
receiver | 外键 User:信息接收人 |
1. Realm模型
- Realm为关系型数据库,每一个表使用一个Model类表示,每一个列对应Model类中的
- 每一个线程可以拥有一个Realm数据链接,使用class Realm类创建一个链接,该类可以实现数据链接,执行查询,更新数据表结构,数据迁移,数据绑定等操作
- 每一个Model类都继承自Realm库中的class Object类,继承后便可进行数据表的增删改查操作
- 数据表之间的关系由Model类中的属性给出,使用class List<T>以及class LinkingObjects表示外键
- 可以通过重载Model类中的函数来定义数据表的一些属性,如func primaryKey函数可以定义表格的主键
官方 Realm Swift 文档(英文) ,旧版本有中文版
2. Realm数据库安装
- 安装CocoaPods
- 在Podfile中添加
use_frameworks!
和pod 'RealmSwift'
- 终端中执行pod install
- 使用.xcworkspace文件启动工程
3. 创建Model
//表User
class User: Object {//属性列@objc dynamic var userName = "庞兴庆"@objc dynamic var mobilePhoneNumber = "18612345678"@objc dynamic var portraitImage = Data()@objc dynamic var qrcodeImage: Data? = nil//外键let following = List<User>()let fans = LinkingObjects(fromType: User.self, property: "following")let cars = List<Car>()let apps = List<Appointment>()let enrollapps = List<Appointment>()let sendmessages = List<Message>()let receivemessages = List<Message>()//创建主键override class func primaryKey() -> String? {return "userName"}
}
- 创建数据表User对应的Model:只要这个类继承自Realm中的Object类即可
- 创建数据表User中的属性列:使用@objc dynamic var PropertyName = defaultValue形式进行创建,对于必填的列(Non-optional)以及非必填列(Optional)的属性定义方式由下表给出。Object,List,LinkingObjects都可以用于外键对应的列
Type | Non-optional | Optional |
---|---|---|
Bool |
@objc dynamic var value = false
|
let value = RealmOptional<Bool>()
|
Int |
@objc dynamic var value = 0
|
let value = RealmOptional<Int>()
|
Float |
@objc dynamic var value: Float = 0.0
|
let value = RealmOptional<Float>()
|
Double |
@objc dynamic var value: Double = 0.0
|
let value = RealmOptional<Double>()
|
String |
@objc dynamic var value = ""
|
@objc dynamic var value: String? = nil
|
Data |
@objc dynamic var value = Data()
|
@objc dynamic var value: Data? = nil
|
Date |
@objc dynamic var value = Date()
|
@objc dynamic var value: Date? = nil
|
Object | n/a: must be optional |
@objc dynamic var value: Class?
|
List |
let value = List<Type>()
|
n/a: must be non-optional |
LinkingObjects |
let value = LinkingObjects(fromType: Class.self, property: "property")
|
n/a: must be non-optional |
- 创建数据表User中的外键:Realm支持一对一、一对多、多对多、以及反向外键,Object与List用于前两种情况
- 创建鼠标表User中的反向外键:LinkingObjects用于定义反向外键,如Car类中的owner类就可以反向查找到拥有者,不需要额外执行查询操作
- 创建数据表User中的主键:重载primaryKey可以定义表格的主键,重载indexedProperties可以定义自增加列,重载ignoredProperties可以定义Model中需要忽略的属性
用同样的方式定义Car类,Appointment类,Message类
4. 实现CreateRandomDatabase函数创建初始数据库
创建数据库、删除数据库
//删除数据库
let realmURL = Realm.Configuration.defaultConfiguration.fileURL!
print(realmURL)
let realmURLs = [realmURL,realmURL.appendingPathExtension("lock"),realmURL.appendingPathExtension("note"),realmURL.appendingPathExtension("management")
]
for URL in realmURLs {do {try FileManager.default.removeItem(at: URL)} catch {// handle error}
}
- Realm数据库会在当前的iOS应用程序中创建4个文件,realm数据库;realm lock文件;realm note文件;realm management文件
- 使用Realm.Configuration.defaultConfiguration.fileURL可以打印出上述四个文件的位置
- 可以通过配置Configuration文件修改Realm数据库的一些特性,比如数据迁移(下文)
- 用FileManager删除当前已经存在的所有Realm数据库文件
var realm = try! Realm()
- 创建一个Realm数据库链接,默认情况下链接的为上文中的realm数据库
- 可以使用Configuration类为Realm配置其他属性,如加载外部数据库,加载内存数据,加载远程数据库,数据迁移等
创建Model实例,修改Model实例,删除Model实例,增、删、改操作
//进行Realm数据库写入,在该范围内对Model的任何修改都会自动保存至Realm数据库中
try! realm.write {//创建User实例let newuser = User()//向Realm数据库,User表中添加一行realm.add(newuser)//为Car表添加一行let newcar = Car()newcar.brand = randombrands[Int.random(in: 0..<randombrands.count)]newcar.color = randomcolors[Int.random(in: 0..<randomcolors.count)]newcar.id = randomcarids[Int.random(in: 0..<randomcarids.count)]//创建外键,反向外键由Realm自动创建newuser.cars.append(newcar)realm.add(newcar)//在write域中,所有对Realm Model的修改都会自动保存//反射赋值newuser.setValue("18612345678", forKeyPath: "mobilePhoneNumber")//直接赋值newuser.userName = usernewuser.portraitImage = UIImage(named: "\(Int.random(in: 1...15))")!.pngData()!newuser.qrcodeImage = UIImage(named: "\(Int.random(in: 1...15))")!.pngData()!
}
- 创建一个表的行:Swift中创建一个Model的实例,如果要对列进行赋值只要只接修改属性值即可
- 为表添加一行:使用add方法才会向Realm数据库中添加一样
- 更新行数据:只要在write域中,所有对Realm Model的更新都是自动的
- Realm还支持使用key-value(反射)的方式对Model中的属性进行赋值
- 使用Realm.delete方法可以删除Model实例
查询Model,查询、排序、分页操作
//查询,filter
//从数据库中获取当前登录用户的信息,User实例
currentUser = realm.objects(User.self).filter("userName = '别摸我咬你哦'").first!//排序,sort
//获取所有可用预约,并按照创建时间进行排序
apps = realm.objects(Appointment.self).sorted(by: { $0.createDate > $1.createDate})//限制查询数量,limit
//查询所有可用用户
let users = realm.objects(User.self)
//只获取前两个用户的数据
for user in 0..<2 {//do something
}//分页操作,page,skip
let currentPage = P
let pageItemCount = N
let users = realm.objects(User.self)
//只获取第P页的N个用户数据
for user in P * N..< (P + 1) * N {//do something
}
- Realm支持查询、排序、链接查询、有限查询操作
- Realm使用懒加载(同C#的LINQ),只有当真正读取查询结果时才会加载数据,因此代码中currentUser和apps两行是不会产生延迟的,因为并没有真正的读取数据
- Realm使用filter+predicate(断言)的方式进行查询,predicate为Apple查询语法,查看 Apple断言编程指南,Realm已经整理好了一个列表可以进行快速查询,Realm 断言帮助手册
- 由于Realm使用懒加载进行查询,所以如果想要限定查询数量(limit)或者进行分页(page/skip),只要使用for循环即可
5. 数据库结构更新,迁移
let newSchemaVersion: UInt64 = 1
let config = Realm.Configuration(//设定当前数据库结果的版本号,默认从0开始,每次更新数据库结构都要增加1schemaVersion: newSchemaVersion,//数据库迁移模块migrationBlock: { migration, oldSchemaVersion in//对比当前APP中数据库版本号与新的版本号,如果较低则更新APP中的数据库结构if (oldSchemaVersion < newSchemaVersion) {// 如果不涉及到数据合并与重命名// 只是增加或者删除列,不需要进行任何操作// Realm会自动进行数据库结构更新// ... do nothing// 如果需要进行列的重命名则需要执行下列操作// 下列操作将User表中的'userName'列更新为'Name'列migration.renameProperty(onType: User.className(), from: "userName", to: "Name")// 如果需要进行列合并或拆分的操作则需要进行下列操作// oldObject:旧数据库结构中的所有列// newObject:新数据库结构中的所有列// Realm会自动对新数据库结构中的列进行赋值// 下列操作将Appointment中'startLocal'和'endLocal'列合并为'Route'列migration.enumerateObjects(ofType: User.className()) { oldObject, newObject in//拆分let startLocal = oldObject!["startLocal"] as! Stringlet endLocal = oldObject!["endLocal"] as! StringnewObject!["Route"] = "from \(startLocal) to \(endLocal)"}}
})//使用上述配置重新打开Realm数据库,Realm会根据配置自动迁移数据库
let realm = try! Realm(configuration: config)
6. 数据绑定,数据更新通知,观察者模式
暂时没用到:Realm Notification
Realm 数据库使用相关推荐
- Realm数据库拾遗
支持数据库加密 // 产生随机密钥 NSMutableData *key = [NSMutableData dataWithLength:64]; SecRandomCopyBytes(kSecRan ...
- Realm数据库存储 使用详解
文章目录 一 Realm 框架 概念介绍 开发辅助工具 二 Realm 使用教程 1 简单的数据操作 创建数据模型 使用RLMRealm对象保存指定模型 使用RLMRealm对象 更新指定模型 使用R ...
- Realm数据库版本迁移
当你和数据库打交道的时候,你需要改变数据模型(Model),但是因为Realm中的数据模型被定义为标准的Objective-C interfaces,要改变模型,就像改变其他Objective-C i ...
- ios realm 文件_iOS Realm数据库使用
Realm 是 SQLite 和 Core Data 的替代者,得益于其零拷贝的设计,Realm 比任何 ORM 都要快很多. Objective‑C版本的 Realm 能够让您以一种安全.耐用以及迅 ...
- Android Realm数据库
In this tutorial, we'll be discussing the basics of Realm Database and implement it in our Android A ...
- android开发收藏功能实现,Android使用Realm数据库如何实现App中的收藏功能
Android使用Realm数据库如何实现App中的收藏功能 发布时间:2021-05-07 11:20:34 来源:亿速云 阅读:63 作者:小新 这篇文章主要介绍了Android使用Realm数据 ...
- android收藏功能demo,Android使用Realm数据库实现App中的收藏功能(代码详解)
前 言 App数据持久化功能是每个App必不可少的功能,而Android最常用的数据持久化方式主要有以下的五种方式: 使用SharedPreferences存储数据: 文件存储数据: SQLite数据 ...
- Realm数据库的使用
文章目录 写在前面 简单使用 几个概念 1. 数据模型 2. 事务 3. 引用计数 4. 数据库的迁移 添加配置文件 初始化Realm并配置Realm 1. 在application的`onCreat ...
- Android Realm数据库完美解析
转自 http://blog.csdn.net/fesdgasdgasdg/article/details/51897212 demo http://download.csdn.net/detai ...
- 如何在Android中使用Realm数据库
我们都知道使用SQLite的本地数据库,它在Android 开发中用于内部存储器存储,主要存储本地数据,如联系人,电话详细信息等.现在我发现一个比SQLite更轻的数据库,被称为Realm数据库,我想 ...
最新文章
- kentico中自定义错误页面
- lua学习笔记之元表和元方法
- 演练3-1:留言管理系统的制作
- 【Java代码】反射机制处理传递给mapper文件的非Map类型参数对象(指定属性为空则设置默认值)
- HDCVI——一种创新性的高清视频传输方案
- 利用dft的定义计算dft的matlab程序_CP2K教程系列之静态计算(Pymatflow篇)
- UI测试常见BUG汇总
- springMVC的流程
- 【华为云技术分享】【Python算法】分类与预测——决策树
- 离散事件模拟(银行业务模拟。实现算法3.6、3.7的程序)
- LAMP 之 Apache 用户认证
- Bailian2930 加减乘除【水题】
- linux中的ps fx命令,Linux中的ps命令
- umount device is busy
- cop2000计算机组成原理,COP2000计算机组成原理实验系统.pdf
- 为什么越来越多的企业选择使用aps生产排产软件?
- 互联网舆情监测与分析系统作用及使用功能详解
- LNMP添加、删除虚拟主机
- 复合隐写/图片混合/图片格式头修改-西伯利亚大尾巴狼
- OpenCV-分水岭算法
热门文章
- org.apache.catalina.startup.Catalina start之过程分析
- 拍照识别文字的软件哪个好?分享三个照片识别文字工具给你
- 第19章 Linux电源管理的系统架构和驱动之CPUIdle驱动
- rar自解压到64位操作\system32中的解决方法
- [转]Show Stopper 一次 crash 调试的夺命狂奔
- 豪情哥的忠告 能做到这一条就够用了
- 基于SDM450 兼容st7701s不同id屏幕
- UVa 10562 Undraw the Trees 看图写树
- 用hutool将数字转简体中文和繁体中文,支持金额模式
- ChianStore区块链应用商店_让小白也能轻松下载区块链应用