iT邦幫忙

3

[Swift] Realm.io 資料庫介紹 - 其之三:查詢、排序、鍵結、自動更新、筆數

  • 分享至 

  • xImage
  •  

[前言]
第一篇的查詢介紹只是小小的做了個全查詢和部份條件查詢。
事實上realm提供的條件不僅僅於此。
畢竟,我們不可能查資料是做全部查詢。一定會有針對性的條件。
請注意,這邊的範例是當你有把realm設成全域變數時才直接使用。
如果你沒有設定成全域變數。那就一定要先下:
let realm = try! Realm()

[條件]
用法 : realm.objects(RLM_Entity).filter(條件)

let results = realm.objects(RLM_User.self).filter("age < 40")

這個做法就是找出年齡不滿40歲的所有使用者資料。

搜尋條件的比較一共有以下幾種:
==, <=, <, >=, >, !=, and BETWEEN
(註:但是和mysql一樣的,其實你用一個「 = 」也會是比較相等值,而非程式結構的「賦值」)

搜尋字串比較的有以下幾種(相當於mysql的like)
==, !=, BEGINSWITH, CONTAINS, and ENDSWITH
BEGINSWITH : 字串開頭為……

//找出字串開頭有Sa的所有使用者
let results = realm.objects(RLM_User.self).filter("name BEGINSWITH 'Sa'")

ENDSWITH : 字串結尾為…

//找出字串結尾有am的所有使用者
let results = realm.objects(RLM_User.self).filter("name ENDSWITH 'am'")

CONTAINS : 字串包含…

//找出字串包含a的所有使用者
let results = realm.objects(RLM_User.self).filter("name CONTAINS 'a'")

條件式有以下幾種:
AND, OR, and NOT

//找出字串包含a及年齡未滿40歲的所有使用者
let results = realm.objects(RLM_User.self).filter("age < 40 AND name CONTAINS 'a'")

[排序]
用法:
(1)realm.objects(RLM_Entity).sorted(byKeyPath: 欄位 )
此用法預設正排序
(2)realm.objects(RLM_Entity).sorted(byKeyPath: 欄位 , ascending: Bool )
此用法Bool為true時是正排序,false時為逆排序

//取出資料並將年齡由小排到大
let results = realm.objects(RLM_User.self).sorted(byKeyPath: "age")

//取出資料並將年齡由小大排到小
let results = realm.objects(RLM_User.self).sorted(byKeyPath: "age", ascending: false)

關聯排序:
(因為尚未講到關聯,這邊僅先舉例,等日後了解關聯自然就明白用法)
以下是假設user上層有group管理,而要將group中取出的user依照年齡排序:

let results = realm.objects(RLM_Group.self).sorted(byKeyPath: "user.age")

(你要我怎麼說?請記得:realm的關聯很強大!很強大!很強大!(說三次))

[鏈接]
官方手冊有講到這個。
但其實他就是指像filter或是sorted是可以用連續鍵接來達成複式條件的。
這邊我直接貼官方的範例:

let tanDogs = realm.objects(Dog.self).filter("color = 'tan'")
let tanDogsWithBNames = tanDogs.filter("name BEGINSWITH 'B'")

這有什麼好處?如果你需要不同的條件產生的各式結果,你不需要重複的使用realm.objects()
你可以用鏈接來繼續往下取你要的資料。

[自動更新結果]
(又一個強大的東西出現了。)
什麼是自動更新結果?
例如:

let results = ream.objects(RLM_User.self)
print(results.count)
let user = RLM_User()
user.name = "eagle"
user.age = "28"
user.address = "No sheep"
try! realm.write {
    realm.add(user)
}
print(results.count)

這是新增一筆資料。
假設原本資料只有1筆,則上面的print(results.count)的結果就會是1。
之後執行了新增資料。
在其他的資料庫系統,你可能需要重新取資料來取得更新後的結果。
但是realm完全不需要這樣做。
上面的程式碼第二次的print(results.count)會告訴你結果是2
而且裡面的資料整個也都變動成新的狀態了。
如此一來你可以省去重新載入資料的動作。

[筆數]
在別的資料庫系統,我們會看到LIMIT這樣的語法。
但是在realm的系統中不存在這樣的東西。
事實上,realm的封裝中,他的資料取得也並非當下就把全部的資料取出。
這和你過程中做的動作有關。
(這也就是為什麼realm取回的型態是Results而非Array的原因。)
(官方的說明翻譯過來是說realm取資料的方式是lazy而非一次取得,所以無需擔心資源的問題)
也就是說,如果你要取得資料筆數………就很單純的寫迴圈來處理就好了。
//假設我要取得資料的21~40筆

let results = ream.objects(RLM_User.self)
for i in 20...39 {
    if let user = result[i] {
        print(user.name)
    }
}

他就是這樣處理。

[群組]
賣鬧啊!
我知道玩資料庫的會想說把一些共同資料對應一定的群組名稱。
比如取得父表的資料再用子表對應父表的名稱來屬於同一群組。
但是realm沒有這種東西。
亦即realm「不提供」等同於GROUP BY這種東西。
你不要花時間去想解決這個,realm沒有提供直接解這個東西的做法。
但不表示你做不出類似的效果。
這就是再接下來會講到realm非常強大的「關聯」。
有這種東西根本就不要去管GROUP BY了。
再下一篇文章,就會講到關於realm的 List的型態。
以及強大的反向關聯……這絕對是整個realm最重要的架構。
那東西強大到讓你省很多事。

--
[目次]
[Swift] Realm.io 資料庫介紹 - 其之一:初探CRUD
[Swift] Realm.io 資料庫介紹 - 其之二:Migrations 遷移
[Swift] Realm.io 資料庫介紹 - 其之三:查詢、排序、鍵結、自動更新、筆數


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
老鷹(eagle)
iT邦高手 1 級 ‧ 2017-03-07 10:49:56

SAM你是要現在開始寫鐵人賽阿

/images/emoticon/emoticon01.gif

看更多先前的回應...收起先前的回應...

現在寫是鐵腿人賽好嗎?
而且打從一開始我想寫東西就不是為了要參賽的。
不會有時間壓力。
也能隨興發揮。

那你可以寫 可樂是怎麼養成的

/images/emoticon/emoticon01.gif

老鷹養成計劃你看怎麼樣?
/images/emoticon/emoticon32.gif

養我請給我1000萬台幣 謝謝~~!

/images/emoticon/emoticon39.gif

我要留言

立即登入留言