CoreData
Core Data比SQLite做了更進(jìn)一步的封裝奠骄,SQLite提供了數(shù)據(jù)的存儲(chǔ)模型仗谆,并提供了一系列API,你可以通過(guò)API讀寫(xiě)數(shù)據(jù)庫(kù)蚤认,去處理想要處理的數(shù)據(jù)凹蜈。但是SQLite存儲(chǔ)的數(shù)據(jù)和你編寫(xiě)代碼中的數(shù)據(jù)(比如一個(gè)類(lèi)的對(duì)象)并沒(méi)有內(nèi)置的聯(lián)系限寞,必須你自己編寫(xiě)代碼去一一對(duì)應(yīng)。
而Core Data卻可以解決一個(gè)數(shù)據(jù)在持久化層和代碼層的一一對(duì)應(yīng)關(guān)系仰坦。也就是說(shuō)履植,你處理一個(gè)對(duì)象的數(shù)據(jù)后,通過(guò)保存接口悄晃,它可以自動(dòng)同步到持久化層里玫霎,而不需要你去實(shí)現(xiàn)額外的代碼。
數(shù)據(jù)模型中的“表格” - Entity
“屬性” - Attributes
“關(guān)系” - Relationship
to one和to many
通過(guò)type可以設(shè)置1對(duì)1或者1對(duì)多
NSPersistentContainer 倉(cāng)庫(kù)管理者
用于創(chuàng)建對(duì)象。
let container = NSPersistentContainer(name: "Model")
container.loadPersistentStores { (description, error) in
if let error = error {
fatalError("Error: \(error)")
}
print("Load stores success")
}
}
表格屬性信息的提供者 -NSManagedObjectModel
let entities = container.managedObjectModel.entities
print("Entity count = \(entities.count)\n")
for entity in entities {
print("Entity: \(entity.name!)")
for property in entity.properties {
print("Property: \(property.name)")
}
print("")
}
}
Entity: Book
Property: isbm
Property: name
Property: page
Property: borrowedBy
Entity: Reader
Property: idCard
Property: name
Property: borrow
數(shù)據(jù)業(yè)務(wù)的操作員 - NSManagedObjectContext
增
let context = container.viewContext
let book = NSEntityDescription.insertNewObject(forEntityName: "Book",
into: context) as! Book
book.name = name
book.isbm = isbm
book.page = Int32(pageCount)
if context.hasChanges {
do {
try context.save()
print("Insert new book(\(name)) successful.")
} catch {
print("\(error)")
}
}
查
let context = container.viewContext
let fetchBooks = NSFetchRequest<Book>(entityName: "Book")
do {
let books = try context.fetch(fetchBooks)
print("Books count = \(books.count)")
for book in books {
print("Book name = \(book.name!)")
}
} catch {
}
篩選 NSPredicate
let context = container.viewContext
let fetchBooks = NSFetchRequest<Book>(entityName: "Book")
fetchBooks.predicate = NSPredicate(format: "name = \"算法(第4版)\"")
do {
let books = try context.fetch(fetchBooks)
print("Books count = \(books.count)")
for book in books {
print("Book name = \(book.name!)")
}
} catch {
print("\(error)")
}
改
let fetchBooks = NSFetchRequest<Book>(entityName: "Book")
fetchBooks.predicate = NSPredicate(format: "isbm = \"9787115293800\"")
do {
let books = try context.fetch(fetchBooks)
if !books.isEmpty {
books[0].name = "算法(第5版)"
if context.hasChanges {
try context.save()
print("Update success.")
}
}
} catch {
print("\(error)")
}
刪
let fetchBooks = NSFetchRequest<Book>(entityName: "Book")
fetchBooks.predicate = NSPredicate(format: "isbm = \"9787115293800\"")
do {
let books = try context.fetch(fetchBooks)
for book in books {
context.delete(books[0])
}
if context.hasChanges {
try context.save()
}
} catch {
print("\(error)")
}
注意事項(xiàng)
- 確保數(shù)據(jù)模型(ManagedObjectModel)在設(shè)計(jì)階段的正確性庶近,因?yàn)楹罄m(xù)的更改可能會(huì)導(dǎo)致數(shù)據(jù)遷移問(wèn)題翁脆。同時(shí)注意數(shù)據(jù)格式問(wèn)題,避免不必要的轉(zhuǎn)換鼻种。
- 數(shù)據(jù)遷移
- 性能優(yōu)化反番,盡量避免在主線程執(zhí)行耗時(shí)的coredata操作
- 錯(cuò)誤處理,注意數(shù)據(jù)不一致或者崩潰叉钥。
- 數(shù)據(jù)庫(kù)備份恬口。注意排除數(shù)據(jù)庫(kù)文件,指定需要備份的數(shù)據(jù)沼侣,導(dǎo)出,然后考慮是否上傳等歉秫。
- 版本控制蛾洛。
Releam
Realm 的優(yōu)勢(shì):
性能:Realm 的底層存儲(chǔ)引擎專門(mén)為移動(dòng)設(shè)備設(shè)計(jì),因此通常比 Core Data 更快雁芙。這在大型數(shù)據(jù)集上特別明顯轧膘,因?yàn)樗捎昧肆銖?fù)制的架構(gòu)。
簡(jiǎn)單易用的 API:Realm 提供了直觀的面向?qū)ο蟮?API兔甘,使開(kāi)發(fā)人員能夠更容易地創(chuàng)建谎碍、查詢和管理數(shù)據(jù)。它不需要繁瑣的配置或復(fù)雜的操作洞焙。
自動(dòng)數(shù)據(jù)同步:Realm 支持自動(dòng)數(shù)據(jù)同步蟆淀,允許實(shí)時(shí)更新和數(shù)據(jù)共享,特別適用于需要實(shí)時(shí)數(shù)據(jù)的應(yīng)用程序澡匪,如聊天應(yīng)用或協(xié)作工具熔任。
多平臺(tái)支持:Realm 可以輕松支持多個(gè)平臺(tái),包括 iOS唁情、Android疑苔、macOS 和其他平臺(tái)。這使得跨平臺(tái)開(kāi)發(fā)更容易甸鸟。
開(kāi)源和活躍的社區(qū):Realm 是開(kāi)源的惦费,擁有一個(gè)活躍的社區(qū),提供廣泛的文檔和支持抢韭。
Realm 的劣勢(shì):
學(xué)習(xí)曲線:雖然 Realm 的 API 簡(jiǎn)單易用薪贫,但對(duì)于那些熟悉 Core Data 或其他 ORM 框架的開(kāi)發(fā)人員來(lái)說(shuō),可能需要一些時(shí)間來(lái)適應(yīng)篮绰。
少量學(xué)習(xí)資源:相對(duì)于 Core Data后雷,Realm 的學(xué)習(xí)資源和教程數(shù)量較少,因此在解決問(wèn)題時(shí)可能需要更多自學(xué)。
注意事項(xiàng)
版本管理:
Realm 數(shù)據(jù)庫(kù)的數(shù)據(jù)模型版本管理非常重要臀突。每當(dāng)你更改數(shù)據(jù)模型時(shí)勉抓,都應(yīng)該創(chuàng)建一個(gè)新的數(shù)據(jù)模型版本,并編寫(xiě)相應(yīng)的數(shù)據(jù)遷移代碼以確保平滑的升級(jí)候学。Realm支持?jǐn)?shù)據(jù)模型版本控制藕筋,但需要謹(jǐn)慎處理數(shù)據(jù)遷移。
let config = Realm.Configuration(
schemaVersion: 2, // 新的數(shù)據(jù)模型版本
migrationBlock: { migration, oldSchemaVersion in
if oldSchemaVersion < 2 {
// 在舊數(shù)據(jù)模型版本(1)上執(zhí)行遷移邏輯
migration.enumerateObjects(ofType: Person.className()) { oldObject, newObject in
// 執(zhí)行遷移邏輯梳码,例如屬性重命名或數(shù)據(jù)轉(zhuǎn)換
let firstName = oldObject!["name"] as! String
newObject!["firstName"] = firstName
newObject!["lastName"] = ""
}
}
}
)
// 使用新的配置打開(kāi) Realm 數(shù)據(jù)庫(kù)
let realm = try! Realm(configuration: config)