【iOS - 使用Realm來實現增修刪查資料的功能】

Realm 是跨平台的資料庫,支援本地端亦可佈署到雲端上,而目前支援的語言有 Java、Swift、ObjectC、JavaScript、Xamarin 等等,並且都有相對應的 SDK 可供下載,最重要的是官網都有提供相當完整的說明,例如簡單的範例、如何佈署到雲端、有哪些雲端的平台支援 Realm 等等。而與其說 Realm 是資料庫不如說它就是一個特殊格式的檔案,且必須使用特定的工具(Realm Browser)才能打開它,這在後面法蘭克會簡單介紹該工具的使用方式。
Realm 跟同樣是資料庫的 SQLite 比較起來其各有優缺點,以下來看看它們的優缺點為何。
Realm => 入門門檻「低」,非常適合初學者,因不須去理解 SQL 的語法為何,操作上也完全是透過物件關聯的方式。而缺點就是效能不及 SQLite,因為 Realm 中間必須還要透過自有的引擎來轉換其語法。
SQLite = > 入門門檻「高」,必須熟悉 SQL 的語法和了解在 IOS 平台相對應的框架,但在效能上遠優於 Realm。
總結一下就是要考慮當下的開發人員和後續維護的問題來決定使用哪種方式來實作會比較好。以下就開始來介紹 Realm 本地端資料庫的操作。

【前置作業】

  1. 開啟一 Single View Application 的專案並透過 cocoaPods 載入 Swift3 的SDK,但因目前 Realm 只支援到 Swift2,所以如果要使用 Swift3,必須還要在 Podfile 做一些簡單的設定。

若要使用 Swift3 就得如同官網所說明的

在 Podfile 加入以下字段

加入後如下

將該 Podfile 放置剛剛開啟的 Single View Application 下,並執行 「pod update」,注意一定要執行「pod update」否則版本不會是最新的,在後續操作上會有問題產生,安裝完後請再次確認版本為 2.6.2,並打開 xCode clean 和 build 後試著 import RealmSwift 確認 SDK 是否載入成功。

2. 熟悉操作 Realm 的工具 Realm Browser,並利用此機會先建立基礎的觀念

打開 App Store 搜尋「Realm Browser」並下載

在 Lunachpad 找到它後並打開它

產生 Demo 檔。在 Realm Browser 選單選取 Tools → Generate Demo Database 後,並輸入檔案名稱和存放的地方

接著在畫面上會產生兩個檔案一個資料夾,並且會問你要不要立即打開它,這邊選擇「open」來打開它

打開後左側選單有三個物件,在這邊我們把它理解為三個陣列,裡面分別存放著很多物件

每一列理解為一個物件,每個欄理解為一個物件裡的屬性,所以紅框代表的意思就是有一個物件並且有三個屬性

透過工具可以快速的修改資料

3. 以上已對 Realm 有初步的了解了,但這樣似乎還不太夠,可以先快速看一下官方的文件再來開始實作範例, 而且很貼心的 Realm 有提供中文的文件。


【內容大綱】

  1. 新增資料。
  2. 修改資料。
  3. 查詢資料、使用條件過濾資料。
  4. 刪除資料。

在開始實作前,先來說明 Realm 經常會使用到的類別和相關的機制(Transation)。

RLMRealm => 用於管理和資料庫溝通的類別。對於儲存在 Realm 中的資料,都需要先取到 RLMRealm,然後才能對資料庫進行操作。

RLMObject => 自定義的 Realm 類別。要跟資料庫溝通,就得必須創建一個類別且繼承 RLMObject,然後再設計想要儲存的屬性。可以想像成我們剛剛在 Realm Browser 所看到的一列資料。

RLMResults => 執行任何查詢所返回的結果集合,裡面存放著 RLMObjects 類別。可以想像成我們剛剛在 Realm Browser 左側選單所看到的一個項目。

Write Transactions => 交易機制。這是每一種資料庫都存在的特性之一。對於資料庫的操作,例如新增、修改、刪除等等,都必須在同一個 Transaction 完成,如此才可以確保資料的完整性,例如處理一批數百筆的資料,如果處理到一半有一筆資料錯誤即應當還原所有的資料。而 Realm 則提供了 beginWriteTransaction() 和 commitWriteTransaction() 讓我們可以避免這樣的錯誤發生。

在此先說明,為了簡單起見,法蘭克只會使用單一個物件來做增、修、刪、查功能的說明,而 Realm 並不僅僅只有如此而己,它也有提供 1對1、1對多、多對多的設計模式,還有提供 index 的應用等等,這些資訊在官網都有很清楚的提及到,有興趣的可以至官網查看相關的文件。

1. 新增資料

1.1 首先創建一個訂單類別(Order.swift)並繼承 RLMObject,並且設定四個屬性

id => key值,可加快查詢動作

name => 訂單名稱

amount => 訂單金額

createDate => 訂單產生日期

最後覆寫 primaryKey() 方法來告訴 Realm 說要使用自定義的 key 值。

1.2 在 ViewController.swift 的 viewDidLoad() 下加入以下新增的語法

第 2 行 => 生成 Realm 物件,不管增、修、刪、查,若是要與資料庫互動就得先取得它。

第 4~6 行 => 生成訂單,僅需要設定訂單名稱和金額,因 key 和訂單產生日期會自動產生。

第 9~ 11 行 => 在資料庫生成一筆訂單資料,如同前面所說的,為了確保資料的完整性,必須將對資料庫操作的過程放在 beginWriteTransaction() 和 commitWriteTransaction() 之間,而這邊為何沒有放呢?原因如下:

看一下底層的 API 其實已經幫我們做好 Transaction 的管理了

不過呢,如果是多筆資料的話,為了效能考量,就比較不建議用這個方法,因為每提交一次就得必須消耗浪費一次效能,這時就可以使用將對資料庫操作的過程放在 beginWriteTransaction() 和 commitWriteTransaction() 之間,等資料處理完畢後,再一次性的提交,像是這樣:

第 14 行 => 印出資料庫存放的位置,這很重要,因為這個檔案的路徑非常複雜,但它其實是有遵照一定的規則產生的,規則如下 /Users/<username>/Library/Developer/CoreSimulator/Devices/<simulator-uuid>/data/Containers/Data/Application/<application-uuid>/Documents/default.realm

以上程式碼加入後,試著啟動模擬器,這時侯資料已經產生了。以下來說明如何查看產生的資料。

複製 console 印出的檔案路徑

/Users/Frank.Chen/Library/Developer/CoreSimulator/Devices/CBBA8E51–9862–4D1F-B113-BAE2DA281F40/data/Containers/Data/Application/DB439A46–72B6–404C-84F1-B8D463A69BC4/Documents/

將路徑貼到 finder 後,並點選 document 資料夾

將該資料夾加至 finder 的捷徑

雙擊 default.realm 預設會使用 Realm Browser 來打開它,接著就會看到我們剛剛新增的資料了

備註:

因為 Realm 是實體檔案的關係,所以在使用多執行緒同時操作一個檔案時,想必是會有問題發生的,為了避免該問題發生,請確保只能有單一執行緒在處理該檔案。


2. 修改資料

使用 key 值來更新資料,若是該筆資料不存在則會新增

2.1 複製 key 值

2.2 在 ViewController.swift 的 viewDidLoad() 下加入以下修改的語法

第 11 行 => 必須有定義key值才能傳入 true,且若是該 key 值的資料不存在則會新增。

2.3 查看 default.realm 是否已更新


3. 查詢資料、使用條件查詢資料

在查詢前為了要演示查詢條件,請自行再新增兩筆訂單資料

3.1 未帶查詢條件的查詢

第 4 行 => 使用 objects() 並傳入所要查詢的物件。

結果如下:

3.2 使用斷言字串查詢條件來過濾資料

第 4 行 => 使用 filter() 加入條件,這邊可以是多條件,至於寫法可以是錄結式的,也就是 filter().filter()

結果如下:

3.3 使用斷言字串查詢條件來過濾資料

結果如下:

有關於更多條件的使用方法,可參考官方的文件。


4. 刪除資料

刪除訂單金額大於等於 20000 且 小於等於 50000 的資料

第 8 行 => delete() 接受的參數有很多種,可以是 RLMRealm 也可以是 RLMResults


【範例】

最後附上一個使用 Realm 來達成新增、修改、刪除、查詢的範例,請至 GitHub 下載。


【結論】

若有任何問題皆可在下面留言給法蘭克。


Show your support

Clapping shows how much you appreciated 法蘭克的iOS世界’s story.