Core Data

簡介

? Core Data是iOS5之后才出現的一個框架,它提供了對象-關系映射(ORM)的功能,即能夠將OC對象轉化成數據,保存在SQLite數據庫文件中,也能夠將保存在數據庫中的數據還原成OC對象。在此數據操作期間,我們不需要編寫任何SQL語句,這個有點類似于著名的Hibernate持久化框架,不過功能肯定是沒有Hibernate強大的。簡單地用下圖描述下它的作用:

abc

左邊是關系模型,即數據庫,數據庫里面有張person表,person表里面有id、name、age三個字段,而且有2條記錄;

右邊是對象模型,可以看到,有2個OC對象;

利用Core Data框架,我們就可以輕松地將數據庫里面的2條記錄轉換成2個OC對象,也可以輕松地將2個OC對象保存到數據庫中,變成2條表記錄,而且不用寫一條SQL語句。

?

模型文件

在Core Data,需要進行映射的對象稱為實體(entity),而且需要使用Core Data的模型文件來描述app中的所有實體和實體屬性。這里以Person(人)和Card(身份證)2個實體為例子,先看看實體屬性和實體之間的關聯關系:
abc
Person實體中有:name(姓名)、age(年齡)、card(身份證)三個屬性
Card實體中有:no(號碼)、person(人)兩個屬性

接下來看看創建模型文件的過程:
1.選擇模板
abcabc

2.添加實體


3.添加Person的2個基本屬性


4.添加Card的1個基本屬性



5.建立Card和Person的關聯關系

????????

右圖中的表示Card中有個Person類型的person屬性,目的就是建立Card跟Person之間的一對一關聯關系(建議補上這一項),在Person中加上Inverse屬性后,你會發現Card中Inverse屬性也自動補上了

?

?

了解NSManagedObject

?

1.通過Core Data從數據庫取出的對象,默認情況下都是NSManagedObject對象
??

2.NSManagedObject的工作模式有點類似于NSDictionary對象,通過鍵-值對來存取所有的實體屬性

1>?setValue:forKey:存儲屬性值(屬性名為key)

2>?valueForKey:獲取屬性值(屬性名為key)


CoreData中的核心對象



注:黑色表示類名,紅色表示類里面的一個屬性
開發步驟總結:
1.初始化NSManagedObjectModel對象,加載模型文件,讀取app中的所有實體信息
2.初始化NSPersistentStoreCoordinator對象,添加持久化庫(這里采取SQLite數據庫)
3.初始化NSManagedObjectContext對象,拿到這個上下文對象操作實體,進行CRUD操作

代碼實現

先添加CoreData.framework和導入主頭文件<CoreData/CoreData.h>


1.搭建上下文環境
[java]?view plaincopy
  1. //?從應用程序包中加載模型文件??
  2. NSManagedObjectModel?*model?=?[NSManagedObjectModel?mergedModelFromBundles:nil];??
  3. //?傳入模型對象,初始化NSPersistentStoreCoordinator??
  4. NSPersistentStoreCoordinator?*psc?=?[[[NSPersistentStoreCoordinator?alloc]?initWithManagedObjectModel:model]?autorelease];??
  5. //?構建SQLite數據庫文件的路徑??
  6. NSString?*docs?=?[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,?NSUserDomainMask,?YES)?lastObject];??
  7. NSURL?*url?=?[NSURL?fileURLWithPath:[docs?stringByAppendingPathComponent:@"person.data"]];??
  8. //?添加持久化存儲庫,這里使用SQLite作為存儲庫??
  9. NSError?*error?=?nil;??
  10. NSPersistentStore?*store?=?[psc?addPersistentStoreWithType:NSSQLiteStoreType?configuration:nil?URL:url?options:nil?error:&error];??
  11. if?(store?==?nil)?{?//?直接拋異常??
  12. ????[NSException?raise:@"添加數據庫錯誤"?format:@"%@",?[error?localizedDescription]];??
  13. }??
  14. //?初始化上下文,設置persistentStoreCoordinator屬性??
  15. NSManagedObjectContext?*context?=?[[NSManagedObjectContext?alloc]?init];??
  16. context.persistentStoreCoordinator?=?psc;??
  17. //?用完之后,記得要[context?release];??

2.添加數據到數據庫
[java]?view plaincopy
  1. //?傳入上下文,創建一個Person實體對象??
  2. NSManagedObject?*person?=?[NSEntityDescription?insertNewObjectForEntityForName:@"Person"?inManagedObjectContext:context];??
  3. //?設置Person的簡單屬性??
  4. [person?setValue:@"MJ"?forKey:@"name"];??
  5. [person?setValue:[NSNumber?numberWithInt:27]?forKey:@"age"];??
  6. //?傳入上下文,創建一個Card實體對象??
  7. NSManagedObject?*card?=?[NSEntityDescription?insertNewObjectForEntityForName:@"Card"?inManagedObjectContext:context];??
  8. [card?setValue:@"4414241933432"?forKey:@"no"];??
  9. //?設置Person和Card之間的關聯關系??
  10. [person?setValue:card?forKey:@"card"];??
  11. //?利用上下文對象,將數據同步到持久化存儲庫??
  12. NSError?*error?=?nil;??
  13. BOOL?success?=?[context?save:&error];??
  14. if?(!success)?{??
  15. ????[NSException?raise:@"訪問數據庫錯誤"?format:@"%@",?[error?localizedDescription]];??
  16. }??
  17. //?如果是想做更新操作:只要在更改了實體對象的屬性后調用[context?save:&error],就能將更改的數據同步到數據庫??

3.從數據庫中查詢數據
[java]?view plaincopy
  1. //?初始化一個查詢請求??
  2. NSFetchRequest?*request?=?[[[NSFetchRequest?alloc]?init]?autorelease];??
  3. //?設置要查詢的實體??
  4. request.entity?=?[NSEntityDescription?entityForName:@"Person"?inManagedObjectContext:context];??
  5. //?設置排序(按照age降序)??
  6. NSSortDescriptor?*sort?=?[NSSortDescriptor?sortDescriptorWithKey:@"age"?ascending:NO];??
  7. request.sortDescriptors?=?[NSArray?arrayWithObject:sort];??
  8. //?設置條件過濾(搜索name中包含字符串"Itcast-1"的記錄,注意:設置條件過濾時,數據庫SQL語句中的%要用*來代替,所以%Itcast-1%應該寫成*Itcast-1*)??
  9. NSPredicate?*predicate?=?[NSPredicate?predicateWithFormat:@"name?like?%@",?@"*Itcast-1*"];??
  10. request.predicate?=?predicate;??
  11. //?執行請求??
  12. NSError?*error?=?nil;??
  13. NSArray?*objs?=?[context?executeFetchRequest:request?error:&error];??
  14. if?(error)?{??
  15. ????[NSException?raise:@"查詢錯誤"?format:@"%@",?[error?localizedDescription]];??
  16. }??
  17. //?遍歷數據??
  18. for?(NSManagedObject?*obj?in?objs)?{??
  19. ????NSLog(@"name=%@",?[obj?valueForKey:@"name"]??
  20. }??
注:Core Data不會根據實體中的關聯關系立即獲取相應的關聯對象,比如通過Core Data取出Person實體時,并不會立即查詢相關聯的Card實體;當應用真的需要使用Card時,才會再次查詢數據庫,加載Card實體的信息。這個就是Core Data的延遲加載機制

4.刪除數據庫中的數據
[java]?view plaincopy
  1. //?傳入需要刪除的實體對象??
  2. [context?deleteObject:managedObject];??
  3. //?將結果同步到數據庫??
  4. NSError?*error?=?nil;??
  5. [context?save:&error];??
  6. if?(error)?{??
  7. ????[NSException?raise:@"刪除錯誤"?format:@"%@",?[error?localizedDescription]];??
  8. }??

打開CoreData的SQL語句輸出開關

1.打開Product,點擊EditScheme...
2.點擊Arguments,在ArgumentsPassed On Launch中添加2項
1> -com.apple.CoreData.SQLDebug
2> 1



創建NSManagedObject的子類

默認情況下,利用Core Data取出的實體都是NSManagedObject類型的,能夠利用鍵-值對來存取數據。但是一般情況下,實體在存取數據的基礎上,有時還需要添加一些業務方法來完成一些其他任務,那么就必須創建NSManagedObject的子類


選擇模型文件?


選擇需要創建子類的實體?


創建完畢后,多了2個子類?


文件內容展示:
Person.h
[java]?view plaincopy
  1. #import?<Foundation/Foundation.h>??
  2. #import?<CoreData/CoreData.h>??
  3. ??
  4. @class?Card;??
  5. ??
  6. @interface?Person?:?NSManagedObject??
  7. ??
  8. @property?(nonatomic,?retain)?NSString?*?name;??
  9. @property?(nonatomic,?retain)?NSNumber?*?age;??
  10. @property?(nonatomic,?retain)?Card?*card;??
  11. ??
  12. @end??

Person.m
[java]?view plaincopy
  1. #import?"Person.h"??
  2. ??
  3. @implementation?Person??
  4. ??
  5. @dynamic?name;??
  6. @dynamic?age;??
  7. @dynamic?card;??
  8. ??
  9. @end??

Card.h
[java]?view plaincopy
  1. #import?<Foundation/Foundation.h>??
  2. #import?<CoreData/CoreData.h>??
  3. ??
  4. @class?Person;??
  5. ??
  6. @interface?Card?:?NSManagedObject??
  7. ??
  8. @property?(nonatomic,?retain)?NSString?*?no;??
  9. @property?(nonatomic,?retain)?Person?*person;??
  10. ??
  11. @end??

Card.m
[java]?view plaincopy
  1. #import?"Card.h"??
  2. #import?"Person.h"??
  3. ??
  4. @implementation?Card??
  5. ??
  6. @dynamic?no;??
  7. @dynamic?person;??
  8. ??
  9. @end??

那么往數據庫中添加數據的時候就應該寫了:
[java]?view plaincopy
  1. Person?*person?=?[NSEntityDescription?insertNewObjectForEntityForName:@"Person"?inManagedObjectContext:context];??
  2. person.name?=?@"MJ";??
  3. person.age?=?[NSNumber?numberWithInt:27];??
  4. ??
  5. Card?*card?=?[NSEntityDescription?insertNewObjectForEntityForName:@”Card"?inManagedObjectContext:context];??
  6. card.no?=?@”4414245465656";??
  7. person.card?=?card;??
  8. //?最后調用[context?save&error];保存數據??


說到這里,整個Core Data框架的入門就結束了,其實Core Data還遠不止這些功能,它還支持自動撤銷機制,一對多關聯等,這里就不一一介紹了

轉載于:https://www.cnblogs.com/graveliang/p/5825294.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/457323.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/457323.shtml
英文地址,請注明出處:http://en.pswp.cn/news/457323.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

tbase同步mysql_mysql主從同步

MySQL主從介紹MySQL主從叫做Replication、AB復制&#xff0c;A和B做主從后&#xff0c;在A上寫數據。B上也會同步A的數據&#xff0c;兩者實現實時同步MySQL是基于binlog日志來同步的&#xff0c;主上必須開啟binlog才能進行主從同步&#xff0c;同步過程大概有三個步驟(1)主將…

2017將轉行進行到底

2016 年說著轉行&#xff0c;最后還是在匆匆中找了一份老本行&#xff0c;此刻的心情還是無愛&#xff0c;畢竟螺絲一直分不清啊&#xff0c;不喜歡就是不喜歡。看了django的教程&#xff0c;不得不感嘆國外的書寫的相對優秀一點&#xff0c;《learning django web development…

mysql中函數是否可以返回多個值_是否可以從mysql函數返回多個值?

我的臟解決方案是&#xff1a;1.連接字符串中的值. 2返回字符串. 3 Splits將字符串返回值.我認為它不優雅,我確信這有局限性,但它適用于簡單的情況還有必要創建分裂函數,因為Mysql沒有這個函數&#xff1a;首先編輯你的功能.CREATE FUNCTION yourFunctionWith2valuesForReturni…

lua自定義迭代器

迭代器 http://www.tutorialspoint.com/lua/lua_iterators.htm 迭代器能夠讓你遍歷某個集合或者容器中的每一個元素。 對于lua來說&#xff0c; 集合通常指代 table&#xff0c; 用于創建變化的數據結構&#xff0c; 類似數組。 Iterator is a construct that enables you to t…

mysql非主鍵索引_主鍵索引和非主鍵索引的區別

1. 什么是最左前綴原則&#xff1f;以下回答全部是基于MySQL的InnoDB引擎例如對于下面這一張表如果我們按照 name 字段來建立索引的話&#xff0c;采用B樹的結構&#xff0c;大概的索引結構如下如果我們要進行模糊查找&#xff0c;查找name 以“張"開頭的所有人的ID&#…

優美的配色方案設計

2019獨角獸企業重金招聘Python工程師標準>>> 怎么做好設計配色一直是個難題&#xff0c;雖然網站上有各種各樣的色庫&#xff0c;但配色仍然至關重要&#xff0c;不得已的話可以親自動手&#xff0c;況且樂趣滿滿。 這個沒有一套標準&#xff0c;所以看自己怎么喜歡…

It's a start!

開始博客之旅轉載于:https://www.cnblogs.com/catchingdream/p/5843172.html

mysql死鎖釋放時間參數_【Mysql】mysql 事務未提交導致死鎖 Lock wait timeout exceeded; try restarting transaction 解決辦法...

問題場景問題出現環境&#xff1a;1、在同一事務內先后對同一條數據進行插入和更新操作&#xff1b;2、多臺服務器操作同一數據庫&#xff1b;3、瞬時出現高并發現象&#xff1b;不斷的有一下異常拋出&#xff0c;異常信息&#xff1a;org.springframework.dao.CannotAcquireLo…

ORACLE sqlplus設置行數和寬度

1) 查看目前的pagesize,默認是14:Sqlplus代碼show pagesize; 2) 將pagesize設置好100,則可以一次顯示夠多行記錄了:Sqlplus代碼set pagesize 100; 2. 設置行的寬度1) 查看目前的linesize,默認是80:Sqlplus代碼show linesize; 2) 設置成100或者更寬都可以:Sqlplus代碼set li…

mysql關系模式怎么畫_關系數據庫與mysql

表下面是阿里的mysql設計原則&#xff0c;可以參考&#xff0c;不一定按照阿里規則&#xff0c;但一個團隊一定要有規則&#xff0c;如果現在沒有規則&#xff0c;從現在開始&#xff0c;慢慢推廣&#xff0c;適應1.【強制】表達是與否概念的字段&#xff0c;必須使用 is_xxx的…

Javascript 構造函數模式、原型模式

前兩天寫完組合繼承&#xff0c;打算總結一下原型繼承的&#xff0c;不過今天看了一下工廠模式、構造函數模式和原型模式&#xff0c;覺得有必要總結一下以加深印象。 ———————————————————————————————————————————————————…

2016年CCF第七次測試 俄羅斯方塊

1 //2016年CCF第七次測試 俄羅斯方塊2 // 這道小模擬題還是不錯3 // 思路&#xff1a;處理出輸入矩陣中含1格子的行數和列數4 // 再判是否有一個格子碰到底部&#xff0c;否則整體再往下移動一步&#xff0c;如果有一個格子不能移動&#xff0c;要返回到前一步5 6 #include <…

springmvc視圖解析器_SpringMVC視圖及REST風格

什么是視圖解析器&#xff1f;springMVC用于處理視圖最重要的兩個接口是ViewResolver和View。ViewResolver的主要作用是把一個邏輯上的視圖名稱解析成一個真的的視圖&#xff0c;而SpringMVC中用于把View對象呈現給客戶端的是View對象本身&#xff0c;而ViewResolver只是把邏輯…

mysql5.7.x 1251_MySql-8.0.x免安裝版下載與配置,Navicat打開數據庫鏈接報錯1251的解決辦法...

概述MySQL從5.7一下子跳到了MySQL8.0, 其中的變化必然是很大的, 這里就不說了, 本文主要講解最新版MySQL安裝的事情.實際上5.7版本后的mysql免安裝版都是沒有data文件和my.ini文件的&#xff0c;下面再具體說明怎么生成&#xff0c;注意不能自己手動新建.下載下載程序必然去官網…

To install 64-bit ODBC drivers

為了更充分的利用硬件資源&#xff0c;我想很多人都開使用64位操作系統了&#xff0c;同時你可以也發現了在64位操作系統上ODBC的驅動找不到了&#xff0c;所以ODBC的東西都沒法用了。 因為2007以前版本的Office只有32位版本&#xff0c;所以我們不能在64位系統上使用ODBC。使用…

【Qt開發】QTableWidget設置根據內容調整列寬和行高

QTableWidget要調整表格行寬主要涉及以下一個函數 1.resizeColumnsToContents(); 根據內容調整列寬 2.resizeColumnToContents(int col); 根據內容自動調整給定列寬 3.horizontalHeader()->setResizeMode 把給定列…

深入淺出mysql數據開發_深入淺出MySQL數據庫開發、優化與管理維護 PDF掃描版[513KB]...

深入淺出MySQL數據庫開發、優化與管理維護 內容介紹&#xff1a;本書從數據庫的基礎、開發、優化、管理維護4個方面對MySQL進行了詳細的介紹&#xff0c;其中每一部分都獨立成篇。本書內容實用&#xff0c;覆蓋廣泛&#xff0c;講解由淺入深&#xff0c;適合于各個層次的讀者。…

Understand Lambda Expressions in 3 minutes(翻譯)

本文翻譯自CodeProject上的一篇簡單解釋Lambda表達式的文章&#xff0c;適合新手理解。譯文后面我補充了一點對Lambda表達式的說明。 1.什么是Lambda表達式&#xff1f; Lambda表達式是一種匿名方法&#xff0c;多數情況下用來在LINQ中快速創建委托。簡單地說&#xff0c;它代表…

Hibernate二級緩存配置

一、定義&#xff1a; 二級緩存是進程或集群范圍內的緩存&#xff0c;可以被所有的Session共享&#xff0c;是可配置的插件 二、二級緩存原理圖 解析&#xff1a;每次從二級緩存中取出的對象&#xff0c;都是一個新的對象。 三、配置步驟如下&#xff1a; 同理&#xff1a;以員…

redis配置主從沒效果_跟我一起學Redis之加個哨兵讓主從復制更加高可用

Redis哨兵(Sentinel)其實本質就是一個RedisServer節點&#xff0c;通過設置 運行模式 來開啟哨兵的功能&#xff1b;主要功能如下&#xff1a;監控(Monitoring )&#xff1a;哨兵節點會不斷地檢查的主服務和從服務的運行狀態&#xff1b;自動故障遷移(Automatic failover) &…