IOS Realm使用小記

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')
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章