数据持久化方案四----CoreData

一、首先创建一个coreData 模型文件
(如:CoreDataTestModel.xcdatamodeld)


0.png

二、创建Model(实体):XLTestModel
XLTestModel.h

@interface XLTestModel : NSObject
@property (nonatomic, copy) NSString *school;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, copy) NSString *recordId;
@end

XLTestModel.m

@implementation XLTestModel

@end

三、创建Entity(实例):(XLTestEntity)

(一)、图示


1.png
2.png

(二)四个文件:
1、配置Entity的属性


image.png

2、要设置CoreData的Tool Version:(建议手动可以,随时查看定位)
<1>手动生成管理,2个分类(CoreDataProperties、CoreDataClass)
在Xcode7及以前时代,手动管理,生成2个分类4个文件
XLTestEntity+CoreDataProperties.h

#import "XLTestEntity+CoreDataClass.h"

@interface XLTestEntity (CoreDataProperties)

+ (NSFetchRequest<XLTestEntity *> *)fetchRequest;

@property (nullable, nonatomic, copy) NSString *school;
@property (nullable, nonatomic, copy) NSString *name;
@property (nonatomic) int64_t age;
@property (nullable, nonatomic, copy) NSString *recordId;
@property (nullable, nonatomic, copy) NSString *mySelfID;

@end

XLTestEntity+CoreDataClass.m

@implementation XLTestEntity (CoreDataProperties)

+ (NSFetchRequest<XLTestEntity *> *)fetchRequest {
    return [NSFetchRequest fetchRequestWithEntityName:@"XLTestEntity"];
}

@dynamic school;
@dynamic name;
@dynamic age;
@dynamic recordId;
@dynamic mySelfID;

@end

XLTestEntity+CoreDataClass.h

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@interface XLTestEntity : NSManagedObject

@end

#import "XLTestEntity+CoreDataProperties.h"

XLTestEntity+CoreDataClass.m

#import "XLTestEntity+CoreDataClass.h"

@implementation XLTestEntity

@end

<2>自动生成管理,在Xcode8及以后版本,封禁掉自动生成代码,自动管理。
image.png

<3>设置语言,swift(默认),选择objective-c,需要手动修改

四、创建CoreData管理类(CoreDataManager)
CoreDataManager.h

#import <Foundation/Foundation.h>

#import <CoreData/CoreData.h>


//实体model
#import "XLTestModel.h"

//实例class
#import "XLTestEntity+CoreDataClass.h"
#import "XLTestEntity+CoreDataClass.h"

NS_ASSUME_NONNULL_BEGIN

@interface CoreDataManager : NSObject

/*1.
 NSManagedObjectContext(被管理的数据上下文)
 操作实际内容(操作持久层)
 作用:插入数据,查询数据,删除数据
 */
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;

/*2.
 NSManagedObjectModel(被管理的数据模型)
 数据库所有表格或数据结构,包含各实体的定义信息
 作用:添加实体的属性,建立属性之间的关系
 操作方法:视图编辑器,或代码
 */
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;

/*3.
 NSPersistentStoreCoordinator(持久化存储助理)
 相当于数据库的连接器
 作用:设置数据存储的名字,位置,存储方式,和存储时机
 */
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;

/*
 (4)NSManagedObject(被管理的数据记录)
     相当于数据库中的表格记录

 (5)NSFetchRequest(获取数据的请求)
     相当于查询语句

 (6)NSEntityDescription(实体结构)
     相当于表格结构

 (7)后缀为.xcdatamodeld的包
     里面是.xcdatamodel文件,用数据模型编辑器编辑
     编译后为.momd或.mom文件
 */


+ (CoreDataManager*)shareCoreDataManager;

- (void)insertModelWithMySelfID:(NSString *)mySelfID WithModel:(XLTestModel *)model;//增
- (NSArray *)getDataWithMySelfID:(NSString *)mySelfID;//查
- (void)updateModelWithMySelfID:(NSString *)mySelfID WithModel:(XLTestModel *)model;//改
- (void)deletModelWithMySelfID:(NSString *)mySelfID WithModel:(XLTestModel *)model;//删一个
- (void)deleteAllModelWithMySelfID:(NSString *)mySelfID;//删所有

@end

NS_ASSUME_NONNULL_END

CoreDataManager.m

#import "CoreDataManager.h"

@implementation CoreDataManager

@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

+ (CoreDataManager *)shareCoreDataManager {
    static CoreDataManager *coreDataManager;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        coreDataManager = [[CoreDataManager alloc] init];
    });
    return coreDataManager;
}

- (void)saveContext {
    NSError *error = nil;
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil) {
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }
}
#pragma mark - Core Data stack
- (NSManagedObjectContext *)managedObjectContext {
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
        [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return _managedObjectContext;
}

  - (NSManagedObjectModel *)managedObjectModel {
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreDataTestModel" withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return _managedObjectModel;
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"xiaoliCoreData.sqlite"];

    NSError *error = nil;

    /*
     *配置支持 低版本数据库向高版本数据库迁移
     NSMigratePersistentStoresAutomaticallyOption设置为YES,CoreData会试着把低版本的持久化存储区迁移到最新版本的模型文件。
     NSInferMappingModelAutomaticallyOption设置为YES,CoreData会试着以最为合理地方式自动推断出源模型文件的实体中,某个属性到底对应于目标模型文件实体中的哪一个属性。
     */
    //设置版本迁移方案
    NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption:@(YES),NSInferMappingModelAutomaticallyOption:@(YES)};
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    // 创建持久化存储协调器,并将迁移方案的字典当做参数传入
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {

    
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    return _persistentStoreCoordinator;
}

// 返回应用程序 存储目录的URL
- (NSURL *)applicationDocumentsDirectory {
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}


- (void)insertModelWithMySelfID:(NSString *)mySelfID WithModel:(XLTestModel *)model {//增

    NSManagedObjectContext *context = [self managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"XLTestEntity"];
    //谓词---过滤(表名+关系名)
    fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(mySelfID == %@ and name == %@)",mySelfID ,model.recordId];
    NSError *error;
    NSInteger count =  [context countForFetchRequest:fetchRequest error:&error];
    if (count < 1) {
        XLTestEntity *myCollect = [NSEntityDescription insertNewObjectForEntityForName:@"XLTestEntity" inManagedObjectContext:context];
        myCollect.mySelfID = mySelfID;
        myCollect.school = model.school;
        myCollect.name = model.name;
        myCollect.age = model.age;
        myCollect.recordId = model.recordId;
        NSError *error;
        if (![context save:&error]) {
            NSLog(@"保存失败:%@",error);
        }
    }  
}
- (NSArray *)getDataWithMySelfID:(NSString *)mySelfID {//查
    NSMutableArray *myCollects = [[NSMutableArray alloc] init];
    NSManagedObjectContext *context = [self managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"XLTestEntity"];
    fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(mySelfID == %@)",mySelfID];
    NSError *error;

    NSArray *fetchRequestObjects = [context executeFetchRequest:fetchRequest error:&error];
    for (XLTestEntity *myCollect in fetchRequestObjects) {
        XLTestModel *model = [XLTestModel new];
        model.school = myCollect.school;
        model.name = myCollect.name;
        model.age = myCollect.age;
        model.recordId = myCollect.recordId;
        [myCollects addObject:model];
    }
    return myCollects;
}
- (void)updateModelWithMySelfID:(NSString *)mySelfID WithModel:(XLTestModel *)model{//改
    NSManagedObjectContext *context = [self managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"XLTestEntity"];
    fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(mySelfID == %@ and recordId == %@)",mySelfID ,model.recordId];
    NSError *error;
    NSArray *fetchRequestObjects = [context executeFetchRequest:fetchRequest error:&error];
    if (!error) {
        if (fetchRequestObjects.count == 1) {
            XLTestEntity *myCollect = fetchRequestObjects[0];
            myCollect.school = model.school;
            myCollect.name = model.name;
            myCollect.age = model.age;
        
        }
    }
    if ([context hasChanges]) {
        if (![context save:&error]) {
            NSLog(@"更改失败:%@",error);
        }
    }

 }

- (void)deletModelWithMySelfID:(NSString *)mySelfID WithModel:(XLTestModel *)model {//删一个
    NSManagedObjectContext *context = [self managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"XLTestEntity"];
    fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(mySelfID == %@ and recordId == %@)",mySelfID ,model.recordId];
    NSError *error;
    NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
    if (!error) {
        for (XLTestEntity *myCollect in fetchedObjects) {
            [context deleteObject:myCollect];
        }
    }
    if ([context hasChanges]) {
        if (![context save:&error]) {
            NSLog(@"删除失败:%@",error);
        }
    }

}
- (void)deleteAllModelWithMySelfID:(NSString *)mySelfID; {//删所有

    NSManagedObjectContext *context = [self managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"XLTestEntity"];
    fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(mySelfID == %@)",mySelfID];
    NSError *error;
    NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
    if (!error) {
        for (XLTestEntity *myCollect in fetchedObjects) {
            [context deleteObject:myCollect];
        }
    }
    if ([context hasChanges]) {
        if (![context save:&error]) {
            NSLog(@"删除失败:%@",error);
        }
    }

}

@end

五、具体实现

//增

for (NSInteger i=0; i<4; i++) {
    XLTestModel *model = [XLTestModel new];
    model.name = [NSString stringWithFormat:@"张%ld", i];
    model.school = @"第一中学";
    model.age = 20+i;
    model.recordId = [NSString stringWithFormat:@"record_%ld", i+1000];
    [[CoreDataManager shareCoreDataManager] insertModelWithMySelfID:@"xiaoli" WithModel:model];
}

//查

NSArray *arr0 = [[CoreDataManager shareCoreDataManager] getDataWithMySelfID:@"xiaoli"];
NSLog(@"%@", arr0);

//改

XLTestModel *model1 = [XLTestModel new];
model1.name = @"王二";
model1.school = @"第-中学";
model1.age = 30;
model1.recordId = @"record_1000";
[[CoreDataManager shareCoreDataManager] updateModelWithMySelfID:@"xiaoli" WithModel:model1];
NSArray *arr1 = [[CoreDataManager shareCoreDataManager] getDataWithMySelfID:@"xiaoli"];
NSLog(@"%@", arr1);

//删一个

XLTestModel *model2 = [XLTestModel new];
model2.recordId = @"record_1003";
[[CoreDataManager shareCoreDataManager] deletModelWithMySelfID:@"xiaoli" WithModel:model2];
NSArray *arr2 = [[CoreDataManager shareCoreDataManager] getDataWithMySelfID:@"xiaoli"];
NSLog(@"%@", arr2);

//删所有

[[CoreDataManager shareCoreDataManager] deleteAllModelWithMySelfID:@"xiaoli"];
NSArray *arr3 = [[CoreDataManager shareCoreDataManager] getDataWithMySelfID:@"xiaoli"];
NSLog(@"%@", arr3);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容