什么是CoreData
CoreData 不是一個數據庫但是可以使用數據庫來存儲數據,也可以使用其他方式,比如:數據庫文件,XML,二進制文件,內存等。CoreData 提供了
對象-關系映射(ORM)
功能。能夠實現數據庫數據和 OC 對象的相互轉換,在這個轉換過程中我們不需要編寫任何 SQL 語句。可以簡單的理解為Cocoa對SQLite的一層封裝
為什么要使用CoreData
極大的減少Model層的代碼量
優化了使用SQLite時候的性能
提供了可視化設計
CoreData框架
CoreData
.xcdatamodeld
文件:定義了數據庫數據和 OC 對象轉換的映射關系,編譯后為.momod
文件NSManagedObjectModel
:負責讀取解析.momod
文件NSPersistentStoreCoordinator
:通過解析結果去實現數據庫和 OC 對象之間的相互轉換,主要是操作數據庫的,我們一般用不上,由系統處理NSManagedObjectContext
:等同于一個容器,用來存儲從數據庫中轉換出來的所有的 OC 對象。我們的增刪改查操作直接對這個類使用來獲得或者修改需要的 OC 對象,它能夠調用NSPersistentStoreCoordinator
類實現對數據庫的同步NSManagedObject
:數據庫中的數據轉換而來的OC對象
*注:
1. 一旦數據創建完畢,就不能再修改.xcdatamodeld文件,如果有修改,必須刪除數據庫重新創建,否則打開數據庫已定會失敗。 去沙盒路徑下把創建的數據庫刪除即可
2. 不能使用alloc init來創建對象
AppDelegate.h
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow * window;
/**
* 上下文 容器
* 存放的是 所有從數據庫中取出的轉換成OC對象
*/
@property (readonly, strong, nonatomic) NSManagedObjectContext * managedObjectContext;
/* 讀取解析 .momd文件中的內容 */
@property (readonly, strong, nonatomic) NSManagedObjectModel * managedObjectModel;
/* 連接的類,處理數據庫數據和OC數據底層的相互轉換 */
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator * persistentStoreCoordinator;
/* 保存 */
-(void)saveContext;
/* 獲取沙盒路徑 */
-(NSURL *)applicationDocumentsDirectory;
@end
AppDelegate.m
#import "AppDelegate.h"
#import "People.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSLog(@"沙盒路徑路徑:%@",[self applicationDocumentsDirectory].absoluteString);
NSLog(@"%@",self.managedObjectContext);
//插入一條數據 (往People表中插入一條數據)
//NSEntityDescription 實體類
//EntityForName 實體名稱(表名)
People * p = [NSEntityDescription insertNewObjectForEntityForName:@"People" inManagedObjectContext:self.managedObjectContext];
//賦值
p.name = @"李四";
p.age = @(25);
p.phone = @"13667895678";
//同步操作 把context中的數據同步到數據庫中
[self saveContext];
// 查詢數據
// 創建查詢請求
NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"People"];
// Context 執行請求(執行查詢操作) 數組中存放的是oc類的對象(People類的對象)
NSArray * array = [self.managedObjectContext executeFetchRequest:request error:nil];
for (People *people in array)
{
NSLog(@"%@",people.name);
}
//查詢特定條件數據 (年齡>20)
NSFetchRequest * request1 = [NSFetchRequest fetchRequestWithEntityName:@"People"];
//使用謂詞指定查詢的判定條件
NSPredicate * predicate = [NSPredicate predicateWithFormat:@"SELF.age > 20"];
//關聯判定條件
[request1 setPredicate:predicate];
//執行查詢操作
NSArray * array2 = [self.managedObjectContext executeFetchRequest:request1 error:nil];
for (People * people in array2)
{
NSLog(@"%@",people.age);
}
//更改數據
//獲取出要修改的數據
People * people2 = [array lastObject];
//修改屬性
people2.name = @"123";
people2.age = @(30);
//同步數據
[self saveContext];
//刪除數據
People * people3 = [array lastObject];
[self.managedObjectContext deleteObject:people3];
//同步數據
[self saveContext];
return YES;
}
//點擊HOME鍵程序直接退出
-(void)applicationWillTerminate:(UIApplication *)application
{
[self saveContext];
}
#pragma mark - Core Data stack
@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
-(NSURL *)applicationDocumentsDirectory
{
//獲取沙盒路徑下documents文件夾的路徑 NSURL (類似于search)
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
//managedObjectModel 屬性的getter方法
-(NSManagedObjectModel *)managedObjectModel
{
if (_managedObjectModel != nil) return _managedObjectModel;
//.xcdatamodeld文件 編譯之后變成.momd文件 (.mom文件)
NSURL * modelURL = [[NSBundle mainBundle] URLForResource:@"CoreData_Class" withExtension:@"momd"];
//把文件的內容讀取到managedObjectModel中
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
//Coordinator 調度者負責數據庫的操作 創建數據庫 打開數據 增刪改查數據
-(NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) return _persistentStoreCoordinator;
//根據model創建了persistentStoreCoordinator
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
// 設置數據庫存放的路徑
NSURL * storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreData_Class.sqlite"];
NSError * error = nil;
//如果沒有得到數據庫,程序崩潰
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
{
NSLog(@"錯誤信息: %@, %@", error, [error userInfo]);
abort(); //崩潰
}
return _persistentStoreCoordinator;
}
//容器類 存放OC的對象
-(NSManagedObjectContext *)managedObjectContext
{
if (_managedObjectContext != nil) return _managedObjectContext;
NSPersistentStoreCoordinator * coordinator = [self persistentStoreCoordinator];
if (!coordinator)
{
return nil;
}
//創建context對象
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
//讓context和coordinator關聯 context可以對數據進行增刪改查功能
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
return _managedObjectContext;
}
#pragma mark - Core Data Saving support
-(void)saveContext
{
NSManagedObjectContext * managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil)
{
NSError * error = nil;
// hasChanges 判斷數據是否更改
// sava 同步數據庫中的數據
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error])
{
NSLog(@"錯誤信息: %@, %@", error, [error userInfo]);
abort();
}
}
}
@end
People.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface People : NSManagedObject
@property (nonatomic, retain) NSNumber * age;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * phone;
@end
People.m
#import "People.h"
@implementation People
/**
* @property 描述對應@synthesize和@synamic兩個關鍵字
* @synthesize 會生成屬性的setter,getter方法
* @dynamic 不生成屬性的setter,getter方法
* 兩個都沒有寫,默認是@synthesize
*/
@dynamic age;
@dynamic name;
@dynamic phone;
@end
參考文獻
微信公共號:iapp666666
GitHub:點此前往