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("[email protected] > 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('@[email protected] > 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')