本地存储coredata和realm

软件产品的两种形态

  • client-server,客户端,本地存储用的较多
  • browser-server,网站,服务器存储用的多,例如mysql

IOS本地存储数据库

  • userdefaults 存储轻量级数据
  • core data 学习成本高,代码较多,速度没有realm快
  • realm 第三方功能包

realm

// 定义模型的做法和定义常规 Swift 类的做法类似,需要继承
class Dog: Object {
    @objc dynamic var name = ""
    @objc dynamic var age = 0
}
class Person: Object {
    @objc dynamic var name = ""
    @objc dynamic var picture: Data? = nil // 支持可空值
    let dogs = List()
}

// 像常规 Swift 对象一样使用
let myDog = Dog()
myDog.name = "Rex"
myDog.age = 1
print("name of dog: \(myDog.name)")

// 获取默认的 Realm 数据库
let realm = try! Realm()

// 检索 Realm 数据库,找到小于 2 岁 的所有狗狗
let puppies = realm.objects(Dog.self).filter("age < 2")
puppies.count // => 0 因为目前还没有任何狗狗被添加到了 Realm 数据库中

// 数据存储十分简单
try! realm.write {
    realm.add(myDog)
}

// 检索结果会实时更新
puppies.count // => 1

// 可以在任何一个线程中执行检索、更新操作
DispatchQueue(label: "background").async {
    autoreleasepool {
        let realm = try! Realm()
        let theDog = realm.objects(Dog.self).filter("age == 1").first
        try! realm.write {
            theDog!.age = 3
        }
    }
}
        let user = User()
        user.name = "gaibb"
        user.age = 21
        
        do {
            let realm = try Realm()
            try realm.write({
                realm.add(user)
            })
        } catch{
            print(error)
        }
        print(Realm.Configuration.defaultConfiguration.fileURL)
  1. objects方法返回一个Results< Element>类型数据
var todos: Results?
todos = realm.objects(Todo.self)
  • 改:直接对获得的Results< Element>类型数据修改
        do {
            try realm.write({
                todos![row].name = name
            })
        } catch  {
            print(error)
        }
            do {
                try realm.write({
                    realm.delete(todos![indexPath.row])
                })
            } catch {
                print(error)
            }

条件搜索

/ 使用断言字符串来查询
var tanDogs = realm.objects(Dog.self).filter("color = 'tan' AND name BEGINSWITH 'B'")

// 使用 NSPredicate 来查询
let predicate = NSPredicate(format: "color = %@ AND name BEGINSWITH %@", "tan", "B")
tanDogs = realm.objects(Dog.self).filter(predicate)
  • 比较操作数可以是属性名,也可以是常量。但至少要有一个操作数是属性名;
  • 比较操作符 ==、<=、<、>=、>、!= 和 BETWEEN 支持 Int、Int8、Int16、Int32、Int64、Float、Double 以及 Date 这几种属性类型,例如 age == 45;
  • 比较是否相同:== 和 !=,例如,Results().filter(“company == %@”, company);
  • 比较操作符 == 和 != 支持布尔属性;
    对于 String 和 Data 属性而言,支持使用 ==、!=、BEGINSWITH、CONTAINS 和 ENDSWITH 操作符,例如 name CONTAINS ‘Ja’;
  • 对于 String 属性而言,LIKE 操作符可以用来比较左端属性和右端表达式:? 和 * 可用作通配符,其中 ? 可以匹配任意一个字符,* 匹配 0 个及其以上的字符。例如:value LIKE ‘?bc*’ 可以匹配到诸如 “abcde” 和 “cbc” 之类的字符串;
  • 字符串的比较忽略大小写,例如 name CONTAINS[c] ‘Ja’。请注意,只有 “A-Z” 和 “a-z” 之间的字符大小写会被忽略。[c] 修饰符可以与 [d] 修饰符结合使用;
  • 字符串的比较忽略变音符号,例如 name BEGINSWITH[d] ‘e’ 能够匹配到 étoile。这个修饰符可以与 [c] 修饰符结合使用。(这个修饰符只能够用于 Realm 所支持的字符串子集:参见当前的限制一节来了解详细信息。)
  • Realm 支持以下组合操作符:“AND”、“OR” 和 “NOT”,例如 name BEGINSWITH ‘J’ AND age >= 32;
  • 包含操作符:IN,例如 name IN {‘Lisa’, ‘Spike’, ‘Hachi’};
  • 空值比较:==、!=,例如 Results().filter(“ceo == nil”)。请注意,Realm 将 nil 视为一种特殊值,而不是某种缺失值;这与 SQL 不同,nil 等同于自身;
  • ANY 比较,例如 ANY student.age < 21;
  • List 和 Results 属性支持聚集表达式:@count、@min、@max、@sum 和 @avg,例如 realm.objects(Company.self).filter(“employees.@count > 5”) 可用以检索所有拥有 5 名以上雇员的公司。
  • 支持子查询,不过存在以下限制:
  1. @count 是唯一一个能在 SUBQUERY 表达式当中使用的操作符;
  2. SUBQUERY(…).@count 表达式只能与常量相比较;

排序

  • 请注意,sorted(byKeyPath:) 和 sorted(byProperty:) 不支持 将多个属性用作排序基准,此外也无法链式排序(只有最后一个 sorted 调用会被使用)。 如果要对多个属性进行排序,请使用 sorted(by:) 方法,然后向其中输入多个 SortDescriptor 对象。
// 对颜色为棕黄色、名字以 "B" 开头的狗狗进行排序
let sortedDogs = realm.objects(Dog.self).filter("color = 'tan' AND name BEGINSWITH 'B'")
	.sorted(byKeyPath: "name")

class Person: Object {
    @objc dynamic var name = ""
    @objc dynamic var dog: Dog?
}
class Dog: Object {
    @objc dynamic var name = ""
    @objc dynamic var age = 0
}

let dogOwners = realm.objects(Person.self)
let ownersByDogAge = dogOwners.sorted(byKeyPath: "dog.age")

你可能感兴趣的:(本地存储coredata和realm)