Swift Realm 使用
之前写过一篇Android的Realm的使用小记,后来接触IOS开发了,现在写一篇在IOS中使用Realm数据库的记录
本文使用的是'RealmSwift','= 3.13.1'
导入
在podfile
文件中加入以下代码
pod 'RealmSwift','= 3.13.1'
执行pod install
命令
使用
基本配置
在AppDelegate文件中加入以下代码
override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
var config = Realm.Configuration(
schemaVersion: 1,
migrationBlock: { migration, oldSchemaVersion in
//数据迁移代码
})
Realm.Configuration.defaultConfiguration = config
}
在开发初期不想关注Realm的迁移,可以使用以下配置
var config = Realm.Configuration(
schemaVersion: 1,
deleteRealmIfMigrationNeeded: true
)
数据迁移
RealmSwift的数据迁移十分简单 一般来说只用修改以下版本号即可
let config = Realm.Configuration(
// 设置新的架构版本。必须大于之前所使用的
// (如果之前从未设置过架构版本,那么当前的架构版本为 0)
schemaVersion: 1,
// 设置模块,如果 Realm 的架构版本低于上面所定义的版本,
// 那么这段代码就会自动调用
migrationBlock: { migration, oldSchemaVersion in
// 我们目前还未执行过迁移,因此 oldSchemaVersion == 0
if (oldSchemaVersion < 1) {
// 没有什么要做的!
// Realm 会自行检测新增和被移除的属性
// 然后会自动更新磁盘上的架构
}
})
// 通知 Realm 为默认的 Realm 数据库使用这个新的配置对象
Realm.Configuration.defaultConfiguration = config
如果你一定要做些什么迁移的话,可以参照以下示例
// enumerateObjects(ofType:_:) 方法将会遍历
// 所有存储在 Realm 文件当中的 `Person` 对象
migration.enumerateObjects(ofType: Person.className()) { oldObject, newObject in
// 将两个 name 合并到 fullName 当中
let firstName = oldObject!["firstName"] as! String
let lastName = oldObject!["lastName"] as! String
newObject!["fullName"] = "\(firstName) \(lastName)"
}
数据查询
增删改都太简单了,这里不赘述了。详情可以看官方文档
1.简单查询
let result : Results<ProjectItp> = realm.objects(ProjectItp.self).filter("NSPredicate:xxxx")
filter传入的参数是一个NSPredicate,可以上网了解一下这个NSPredicate
简单地举几个例子
[c] 表示忽略大小写,该符号可以用于==[c]
!=[c]
BEGINSWITH[c]
CONTAINS[c]
ENDSWITH[c]
LIKE[c]
//用AND 或者 && 连接都可以
filter("lastname == 'fancy' && l_id == 123456 && active == true")
filter("lastname == 'fancy' AND l_id == 123456")
// 字符串比较可以用以下类型 ==、!=、BEGINSWITH、CONTAINS 和 ENDSWITH
filter("lastname CONTAINS 'fancy' )
//忽略大小写
filter("lastname CONTAINS[c] 'fancy' )
太多了,如果要看更详细的 参考官方文档-查询
接下来展示几个例子,在文档中仅是简单提及或者没有提及,且无任何示例代码的查询
2.结果集排序
// 对颜色为棕黄色、名字以 "B" 开头的狗狗进行排序
let sortedDogs = realm.objects(Dog.self).filter("color = 'tan' AND name BEGINSWITH 'B'").sorted(byKeyPath: "name")
//对象属性 可以支持使用`.`符号链接到属性的属性,如果是List则不行
let ownersByDogAge = dogOwners.sorted(byKeyPath: "dog.age")
//对多个属性按照优先级进行排序
let sortedDogs = realm.objects(Dog.self).sorted(by: [SortDescriptor(keyPath: "param1"),SortDescriptor(keyPath: "param2", ascending: true)])
3.去重
//可以传入多个属性, 示例中只传了一个属性
let result : Results<Dog> = realm.objects(Dog.self).filter("appUserId == \(currentUserId) && projectId == \(currentProjectId)").distinct(by: ["favoriteId"])
4.求和
var sumPercent : Int = realm.objects(Dog.self).filter("appUserId == \(currentUserId)").sum(ofProperty: "percentage")
5.查询数量
var count : Int = realm.objects(Dog.self).filter("appUserId == \(currentUserId)").count
6.相似查询
//对于 String 属性而言,LIKE 操作符可以用来比较左端属性和右端表达式:? 和 * 可用作通配符,其中 ? 可以匹配任意一个字符,* 匹配 0 个及其以上的字符。例如:value LIKE '?bc*' 可以匹配到诸如 “abcde” 和 “cbc” 之类的字符串;
//以上文字 从文档中照搬 应该蛮好理解的吧
7.子查询SUBQUERY
//假设有如下数据模型
struct Student {
var id = 0
var name = ""
var score = 0
var courses : List<Course> = List<Course>()
}
struct Course {
var cid = 0
var cname = "" //如高数1,高数2,大学英语1,大学物理1
}
//查询任务如下:查询出所有学生中高数课数量>2的学生
realm.objects(Student.self).filter("SUBQUERY(courses, $course, $course.name contains '高数').@count > 2")
//其中$course,这个是一个遍历时使用的变量名称,可以用任意变量名代替,相应的后面也要改
//如:
realm.objects(Student.self).filter("SUBQUERY(courses, $c, $c.name contains '高数').@count > 2")
8.聚集表达式
//使用例7中的数据模型
//查询任务如下: 课程总数大于5的学生
realm.objects(Student.self).filter("courses.@count > 5")
//其它的@min、@max、@sum 和 @avg我还没想到有什么用
//查询所有课程中编号最大值 > 100的学生
realm.objects(Student.self).filter("courses.@max.cid > 100")
//如果要查询最大值 最小值 总数及平均值 应该使用如下代码:
var max : Int? = result.max(ofProperty: "score")
var min : Int? = result.min(ofProperty: "score")
var sum : Int? = result.sum(ofProperty: "score")
var average : Int? = result.average(ofProperty: "score")
9.关键字 ANY, ALL and NONE
以下摘自文档
//查找 所有朋友中有年龄小于14岁的人
let teens = realm.objects(Contact.self).filtered('ANY friends.age < 14');
//查找 所有朋友的年龄都大于21岁的人
let adults = realm.objects(Contact.self).filtered('ALL friends.age > 21');
10.其他
以下摘自文档
//查询owner叫bob的车
realm.objects(Car.self).filtered('owner.name ==[c] "bob"')
//查询拥有至少一辆honda牌汽车的人
realm.objects(Person.self).filtered('cars.make ==[c] "honda"')
//反向查询拥有至少一辆honda牌汽车的人
realm.objects(Person.self).filtered('@links.Car.owner.make ==[c] "honda"')
//反向查询汽车均价3w以上的的人
realm.objects(Person.self).filtered('@links.Car.owner.@avg.price > 30000')
//查询汽车等于3辆的人
realm.objects(Person.self).filtered('cars.@count == 3')
//反向查询拥有至少一辆honda牌并且价格大于3w的汽车的人
realm.objects(Person.self).filtered('SUBQUERY(@links.Car.owner, $x, $x.make ==[c] "honda" && $x.price > 30000).@count > 1')
//查找谁的汽车全都是honda牌的
realm.objects(Person.self).filtered('ALL @links.Car.owner.make ==[c] "honda"')
//查找没有引入链接的人
realm.objects(Person.self).filtered('@links.@count == 0')