Realm - swift

realm 介紹及安裝

  • 簡(jiǎn)介

Realm 是一個(gè)跨平臺(tái)的移動(dòng)終端數(shù)據(jù)庫,支持 iOS(Swift 和 Objective-C 語言都支持)和 Android。Realm 的目的就是提供比 SQLite 和 Core Data 更好更快的數(shù)據(jù)庫支持。它不僅僅是更好和更快,而且更加易于使用,短短幾行代碼就可以完成很多操作。Realm 完全免費(fèi),你可以隨意使用它。Realm 是為移動(dòng)設(shè)備而生的,因?yàn)樵谶^去的十年中,移動(dòng)終端的數(shù)據(jù)庫技術(shù)沒有任何的革新?,F(xiàn)在如果和移動(dòng)終端的數(shù)據(jù)庫打交道,你只有一種選擇,使用 SQLite 或者是底層封裝了 SQLite 的技術(shù)比如 Core Data。Realm 的目的是更加易用,它并不是一個(gè)建立在 SQLite 之上的 ORM,而是一個(gè)基于自己的持久化引擎,簡(jiǎn)單并且快速的面向?qū)ο笠苿?dòng)數(shù)據(jù)庫。

  • 安裝
    同絕大多數(shù)的第三方庫一樣,Realm也支持三種安裝方式:

    • 項(xiàng)目中直接添加xxx.framework <a >去下載</a>
    • CocoaPods
    • Charthge

    具體安裝方式,可參考官方文檔:<a >Realm</a> 或 <a >Realm(中文說明)</a>

realm 插件及瀏覽器

  • Realm插件

    使用Realm插件的好處是,可以直接使用xcode創(chuàng)建創(chuàng)建數(shù)據(jù)模型文件,基本格式也默認(rèn)搭建好了。
    安裝方式:
    下載 <a >release zip</a> 好后,打開文件中的plugin/RealmPlugin.xcodeproj并進(jìn)行編譯,重啟 Xcode之后插件即可生效。如果您使用 Xcode 菜單來建立一個(gè)新文件(File > New > File… — or ?N) ,您就可以看到有一個(gè)新建Realm模型的選項(xiàng)。效果如下:


    Snip20170221_13.png
  • Realm瀏覽器:Realm Browser
    Realm Browser 可以在appstore直接下載,因?yàn)槊赓M(fèi),所以,不用再通過任何第三方途徑下載安裝破解版的。
    Realm Browser 可以直接打開.realm的文件,或者直接雙擊.reaml文件也是默認(rèn)直接啟動(dòng)Realm Browser

realm 使用及創(chuàng)建

  • 創(chuàng)建.realm文件

    • 默認(rèn)文件

      let reaml = try! Realm()
      

      這句代碼就表示在Docments中創(chuàng)建了一個(gè)default.realm的文件。下面是Realm()初始化方法調(diào)用的方法,對(duì)大家應(yīng)該有收獲:

      public convenience init() throws {
       let rlmRealm = try RLMRealm(configuration: RLMRealmConfiguration.default())
       self.init(rlmRealm)
      

    }
    ```

    • 自定義文件
      如果不想使用默認(rèn)的文件名default.realm或想自定義不同的.realm文件,那么看下面代碼:

      • 修改默認(rèn)的文件名:

        // 數(shù)據(jù)庫的默認(rèn)地址在docments中
        var config = Realm.Configuration()
        config.fileURL = config.fileURL!.deletingLastPathComponent().appendingPathComponent("name.realm")
        Realm.Configuration.defaultConfiguration = config
        
      • 自定義文件:

        // 在docments中創(chuàng)建了一個(gè)Realm1.realm的文件
        let realm1 = try! Realm(configuration: Realm.Configuration(fileURL: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!.appending("/Realm1.realm"))))
        
  • 創(chuàng)建數(shù)據(jù)模型

    • 模型支持的數(shù)據(jù)類型:

      Realm支持以下的屬性類型:Bool、Int8、Int16、Int32、Int64、Double、Float、String、NSDate 以及NSData.
      CGFloat 屬性被取消了,因?yàn)樗念愋筒灰蕾囉谄脚_(tái)。
      String、NSDate 以及 NSData 類型的屬性都可以添加可選值。Object 類型的屬性必須設(shè)置為可選。存儲(chǔ)可空數(shù)字可以通過 Realm 可選值來實(shí)現(xiàn)。

    • 創(chuàng)建模型:
      Realm數(shù)據(jù)模型是基于標(biāo)準(zhǔn) Swift 類來進(jìn)行定義的,使用屬性來完成模型的具體定義。
      通過簡(jiǎn)單的繼承 Object 或者一個(gè)已經(jīng)存在的模型類,您就可以創(chuàng)建一個(gè)新的 Realm 數(shù)據(jù)模型對(duì)象。
      Realm模型對(duì)象在形式上基本上與其他 Swift 對(duì)象相同 - 您可以給它們添加您自己的方法(method)和協(xié)議(protocol),和在其他對(duì)象中使用類似。
      主要的限制是某個(gè)對(duì)象只能在其被創(chuàng)建的那個(gè)線程中使用。
      如果您安裝了我們的Xcode插件 ,那么可在”New File…“對(duì)話框中會(huì)有一個(gè)很漂亮的模板,可用來創(chuàng)建 Swift 文件。

      import RealmSwift
      // 狗狗的數(shù)據(jù)模型
      class Dog: Object {
          dynamic var name = ""
          dynamic var owner: Person? // 屬性可以設(shè)置為可選
      }
      
      // 狗狗主人的數(shù)據(jù)模型
      class Person: Object {
          dynamic var name = ""
          dynamic var birthdate = NSDate(timeIntervalSince1970: 1)
          var dogs = List<Dog>() // let dogs = [Dog] () 包含了嵌套關(guān)系
      }
      

realm 數(shù)據(jù)增加

  • 單個(gè)
    reaml.add(object: Object, update: Bool)
    調(diào)用這個(gè)方法可以添加對(duì)應(yīng)的數(shù)據(jù),object是數(shù)據(jù),update,是指插入的數(shù)據(jù)是否覆蓋相同primaryKey的數(shù)據(jù),如果為true表示覆蓋,如果為false不覆蓋,默認(rèn)為false,這個(gè)屬性必須是唯一的。
    class Dog: Object {
        dynamic var type = ""
        dynamic var name = ""
        dynamic var age = 0
        dynamic var id = ""
        // 主鍵,唯一一行被標(biāo)記的屬性
        override static func primaryKey()-> String {
            return "age" // 必須是屬性,必須是不一樣的內(nèi)容
        }
        
        override static func ignoredProperties() -> [String] {
            return ["type"]
        }
    }

    
        // 實(shí)例化一個(gè)dog對(duì)象
        let dog1 = Dog()
        dog1.name = "dogName"
        dog1.age = 1
        dog1.id = "dog1"
        // 獲取reaml
        let reaml = try! Realm()
        // 加入數(shù)據(jù)
        try! reaml.write {
            reaml.add(dog1,update: true)
       }
  • 多個(gè)
    reaml.add(objects: [Object], update: Bool)
    調(diào)用這個(gè)方法可以添加對(duì)應(yīng)的數(shù)據(jù),object是數(shù)據(jù),update,是指插入的數(shù)據(jù)是否覆蓋相同primaryKey的數(shù)據(jù),如果為true表示覆蓋,如果為false不覆蓋,默認(rèn)為false,這個(gè)屬性必須是唯一的。

    let dog1 = Dog()
       dog1.name = "dogName"
       dog1.age = 1
       dog1.id = "dog1"
       
       let dog2 = Dog()
       dog2.name = "dogName"
       dog2.age = 2
       dog2.id = "dog2"
       
       let dog3 = Dog()
       dog3.name = "Name"
       dog3.age = 3
       dog3.id = "dog3"
       
       let dog4 = Dog()
       dog4.name = "dogName"
       dog4.age = 4
       dog4.id = "dog4"
       
       let dog5 = Dog()
       dog5.name = "lastame"
       dog5.age = 5
       dog5.id = "dog5"
       
       let reaml = try! Realm()
       try! reaml.write {
       reaml.add([dog1,dog2,dog3,dog4,dog5],update: true)
       }
    

realm 數(shù)據(jù)查找

如果您熟悉NSPredicate的話,那么您就能很容易掌握其在 Realm 中的查詢方法。Objects、Realm、List 以及 Results 都提供了方法,允許您通過簡(jiǎn)單地傳遞一個(gè) NSPredicate 實(shí)例、斷言字符串或者斷言格式化字符串來完成查詢這頂Object實(shí)例的操作,正如您在 NSArray 中執(zhí)行查詢的哪樣。

比如說,下面的例子就展示了如何通過從默認(rèn)的 Realm 數(shù)據(jù)庫中調(diào)用 Results().filter(_:...) 方法來檢索所有棕黃色,并且以“大”開頭命名的狗狗的:

    // 使用斷言字符串查詢
    var tanDogs = realm.objects(Dog).filter("color = '棕黃色' AND name BEGINSWITH '大'")
    
    // 使用 NSPredicate 查詢
    let predicate = NSPredicate(format: "color = %@ AND name BEGINSWITH %@", "棕黃色", "大")
    tanDogs = realm.objects(Dog).filter(predicate)

查看蘋果的斷言編程指南來獲取更多關(guān)于斷言查詢和NSPredicate Cheatsheet的使用信息。 Realm 支持許多常見的斷言:

  • 比較操作數(shù)(comparison operand)可以是屬性名稱或者某個(gè)常量,但至少有一個(gè)操作數(shù)必須是屬性名稱;
  • 比較操作符 ==、<=、<、>=、>、!=, 以及 BETWEEN 支持 Int, Int8, Int16, Int32, Int64, Float, Double 以及 NSDate 屬性類型的比較,比如說 age == 45;
  • 相等比較 ==以及!=,比如說Results<Employee>().filter("company == %@", company)
  • 比較操作符 == and != 支持布爾屬性;
  • 對(duì)于 String 和 NSData 屬性來說,我們支持 ==、!=、BEGINSWITH、CONTAINS 以及 ENDSWITH 操作符,比如說 name CONTAINS ‘Ja’;
  • 字符串支持忽略大小寫的比較方式,比如說 name CONTAINS[c] ‘Ja’ ,注意到其中字符的大小寫將被忽略;
  • Realm 支持以下復(fù)合操作符:“AND”、“OR” 以及 “NOT”。比如說 name BEGINSWITH ‘J’ AND age >= 32;
  • 包含操作符 IN,比如說 name IN {‘Lisa’, ‘Spike’, ‘Hachi’};
  • ==、!=支持與 nil 比較,比如說 Results<Company>().filter("ceo == nil")。注意到這只適用于有關(guān)系的對(duì)象,這里 ceo 是 Company 模型的一個(gè)屬性。
  • 通過 ==, != 進(jìn)行空值比較,比如說 Results<Company>().filter("ceo == nil"); 注意,Realm 將 nil 視為一個(gè)特殊的值而不是“缺失值”,不像 SQL 那樣 nil 等于自身。
  • ANY 比較,比如說 ANY student.age < 21 List 以及 Results 屬性支持集合表達(dá)式:@count、@min、@max、@sum 以及 @avg,例如 realm.objects(Company).filter("employees.@count > 5") 用以尋找所有超過 5 名雇員的公司。
  • 支持子查詢,不過有限制:
    @count 是唯一能應(yīng)用在 SUBQUERY 表達(dá)式中的操作符
    SUBQUERY(…).@count 表達(dá)式必須與常量進(jìn)行比較
    相關(guān)子查詢目前還不支持

realm 數(shù)據(jù)修改

Realm 提供了一系列用以更新數(shù)據(jù)的方式,這些方式都有著各自所適應(yīng)的情景。請(qǐng)選擇最符合您當(dāng)前需求的方式來使用:

  • 內(nèi)容直接更新:
    您可以在寫入事務(wù)中通過設(shè)置某個(gè)對(duì)象的屬性從而完成對(duì)象的更新操作。
// 在一個(gè)事務(wù)中更新對(duì)象
let author = ···
try! realm.write {
  author.name = "托馬斯·品欽"
}
  • 鍵值對(duì)更改:
    Object、Result 以及 List都遵守鍵值編碼(Key-Value Coding)(KVC)機(jī)制。 當(dāng)您在運(yùn)行時(shí)才能決定哪個(gè)屬性需要更新的時(shí)候,這個(gè)方法是最有用的。

將 KVC 應(yīng)用在集合當(dāng)中是大量更新對(duì)象的極佳方式,這樣就可以不用經(jīng)常遍歷集合,為每個(gè)項(xiàng)目創(chuàng)建一個(gè)訪問器了。

let persons = realm.objects(Person)
try! realm.write {

// 修改一個(gè)對(duì)象的屬性
  persons.first?.setValue(true, forKeyPath: "isFirst")
  // 將每個(gè)人的 planet 屬性設(shè)置為“地球”
  persons.setValue("地球", forKeyPath: "planet")
}
  • 通過主鍵更新
    如果您的數(shù)據(jù)模型中設(shè)置了主鍵的話,那么您可以使用Realm().add(_:update:)來更新對(duì)象,或者當(dāng)對(duì)象不存在時(shí)插入新的對(duì)象。
// 主鍵,唯一一行被標(biāo)記的屬性
override static func primaryKey()-> String {
   return "age" // 必須是屬性,必須是不一樣的內(nèi)容
}
class Dog: Object {
        dynamic var type = ""
        dynamic var name = ""
        dynamic var age = 0
        dynamic var id = ""
        // 主鍵,唯一一行被標(biāo)記的屬性
        override static func primaryKey()-> String {
            return "age" // 必須是屬性,必須是不一樣的內(nèi)容
        }
        
        override static func ignoredProperties() -> [String] {
            return ["type"]
        }
    }

    
        // 實(shí)例化一個(gè)dog對(duì)象
        let dog1 = Dog()
        dog1.name = "dogName"
        dog1.age = 1
        dog1.id = "dog1"
        // 獲取reaml
        let reaml = try! Realm()
        // 直接更新
        try! reaml.write {
            reaml.add(dog1,update: true)
       }

realm 數(shù)據(jù)刪除

通過在寫入事務(wù)中將要?jiǎng)h除的對(duì)象傳遞給 Realm().delete(_:) 方法,即可完成刪除操作。

// let cheeseBook = ... 存儲(chǔ)在 Realm 中的 Book 對(duì)象

// 在事務(wù)中刪除一個(gè)對(duì)象
try! realm.write {
realm.delete(cheeseBook)
}

// 刪除多個(gè)
let dogs = reaml.objects(Dog.self).filter("age=2")
try! reaml.write {
  reaml.delete(dogs)
}


您也能夠刪除存儲(chǔ)在 Realm 中的所有數(shù)據(jù)。注意,Realm 文件的大小不會(huì)被改變,因?yàn)樗鼤?huì)保留空間以供日后快速存儲(chǔ)數(shù)據(jù)。

// 從 Realm 中刪除所有數(shù)據(jù)
try! realm.write {
  realm.deleteAll()
}

realm 數(shù)據(jù)排序

Results 允許您指定一個(gè)排序標(biāo)準(zhǔn),從而可以根據(jù)一個(gè)或多個(gè)屬性進(jìn)行排序。比如說,下列代碼將上面例子中返回的狗狗根據(jù)名字升序進(jìn)行排序:

// 排序名字以“B”開頭的棕黃色狗狗
let sortedDogs = realm.objects(Dog.self).filter("color = 'tan' AND name BEGINSWITH 'B'").sorted(byProperty: "name")

realm 通知

Realm 實(shí)例將會(huì)在每次寫入事務(wù)提交后,給其他線程上的 Realm 實(shí)例發(fā)送通知:

// 獲取 Realm 通知
let token = realm.addNotificationBlock { notification, realm in
    viewController.updateUI()
}

// 隨后---一般在deinit方法中調(diào)用
token.stop()
文檔參考:

<a >中文文檔 </a>
<a >英文文檔</a>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容