文档章节

CoreData的使用

laoyi007
 laoyi007
发布于 2016/04/16 09:01
字数 1553
阅读 7
收藏 0

CoreData的使用

 

1、使用到的对象

(1)NSManagedObjectContext

操作数据库的上下文(数据库,获取与存储),即负责应用与数据库之间的交互

作用:插入数据、查询数据、删除数据

(2)NSManagedObjectModel

 数据库中所有表格和他们的联系(数据模型),即代表CoreData模型文件,相

 当于实体

 作用:添加实体的属性与类型设置,建立属性之间的关系

 关联:数据模型地址(NSURL)、

 (3)NSPersistentStoreCoordinator/NSPersistentStore

 数据库存放方式(中介、存储数据),即处理数据存储的链接

 作用:设置数据存储的名字、位置、存储方式、存储时机

 关联:数据模型(NSManagedObjectModel)、存储位置(NSURL)、存储方式(NSSQLiteStoreType)、存储时机(NSString)、存储迁移(NSDictionary)

(4)NSManagedObject

 表格的记录(数据对象,管理属性)

(5)NSFetchRequest

 查询语句(请求数据,排序/条件/数量)

 关联:查询条件(NSPredicate)、查询排序(NSSortDescriptor)、查询数量(NSNumber)

注意:后缀为.xcdatamodeld的包,里面是.xcdatamodel文件,用数据模型编辑器编辑,编译后为.momd.mom文件。

 

二、实操

(1)创建CoreData的Model。



(2)创建实体,并设置实体中的属性、属性类型。


(3)创建与实体对应的数据对象,以便于管理属性对象。





 

三、版本升级

当数据库版本升级时,即版本迭代后,数据库中的原实体新增加了属性,或新增加了实体,必须做相应的处理,以避免crash情况。

(1)新增属性,或新增实体后出现异常提示

 


(2)解决:增加版本号处理。(注意:使用系统默认生成的新版本名称,切忌进行修改)


 

四、代码

(1)封装类

.h文件

#import <Foundation/Foundation.h>

#import <CoreData/CoreData.h>

 

@interface CoreDataManager : NSObject

 

/**

*  单例模式

*

@return CoreDataManager

*/

+ (CoreDataManager *)shareManager;

 

/**

 *  创建空的表映射对象

 *

 * @param entityName entityName实体描述名

 *

 * @return id实体类对象

 */

-(id)createEmptyObjectWithEntityName:(NSString *)entityName;

 

/**

 *  查询托管对象上下文中的对象

 *

 * @param predicate        predicate查询条件

 * @param sortDescriptions sortDescriptions排序条件

 * @param entityName       entityName实体描述名

 * @param limitNum         limitNum返回总个数

 *

 * @return NSArray

 */

- (NSArray *)getListWithPredicate:(NSPredicate*)predicate sortDescriptors:(NSArray *)sortDescriptions entityName:(NSString*)entityName limitNum:(NSNumber *)limitNum;

 

/**

 *  删除托管对象上下文中的一个对象

 *

 * @param object object需要删除的任意对象

 *

 * @return BOOL

 */

- (BOOL)deleteObject:(NSManagedObject*)object;

 

/**

 *  删除托管对象上下文中的一个对象

 *

 * @param object   object需要删除的任意对象

 * @param complete complete block回调

 */

- (void)deleteObject:(NSManagedObject*)object complete:(void (^)(BOOL isSuccess))complete;

 

/**

 *  删除托管对象上下文中的所有对象

 *

 * @param entityName entityName实体描述名

 *

 * @return BOOL

 */

-(BOOL)deleteAllObjectWithEntityName:(NSString *)entityName;

 

/**

 *  删除托管对象上下文中的所有对象

 *

 * @param entityName entityName实体描述名

 * @param complete   complete block回调

 */

- (void)deleteAllObjectWithEntityName:(NSString*)entityName complete:(void (^)(BOOL isSuccess))complete;

 

/**

 *  保存托管对象上下文中的更改

 *

 * @return BOOL

 */

- (BOOL)save;

 

/**

 *  保存托管对象上下文中的更改

 *

 * @param complete complete block回调

 */

- (void)save:(void (^)(BOOLisSuccess))complete;

 

@end

 

.m文件

#import "CoreDataManager.h"

 

// 数据库名称

static NSString *const CoreDataSQLiteName =@"CoreDataCache.sqlite";

 

@interface CoreDataManager ()

 

@property (nonatomic, strong)NSManagedObjectContext *objectContext; // 托管对象上下文

 

@end

 

@implementation CoreDataManager

 

/// 数据库存储路径(document)

NSString *GetDocumentPathFileName(NSString*lpFileName)

{

   NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);

   if (paths && 0 != paths.count)

    {

       NSString *documentsDirectory = [paths objectAtIndex:0];

       if (documentsDirectory && 0 != documentsDirectory.length)

       {

           if (lpFileName && 0 != lpFileName.length)

           {

                NSString *filePath =[documentsDirectory stringByAppendingPathComponent:lpFileName];

                return filePath;

           }

       }

    }

   

   return nil;

}

 

- (id)init

{

   self = [super init];

   if (self)

    {

       if (!self.objectContext)

       {

           // 指定存储数据文件(CoreData是建立在SQLite之上的,文件后缀名为:xcdatamodel)

           NSString *persistentStorePath =GetDocumentPathFileName(CoreDataSQLiteName);

           NSURL *storeUrl = [NSURL fileURLWithPath:persistentStorePath];

 

           // 数据迁移

           NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:

                                     [NSNumbernumberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,

                                     [NSNumbernumberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

           

           

           // 创建托管对象模型

           NSURL *modelURL = [[NSBundle mainBundle]URLForResource:@"CacheModel" withExtension:@"momd"];

           NSManagedObjectModel *managedObjectModel = [[NSManagedObjectModel alloc]initWithContentsOfURL:modelURL];

           

           // 创建持久化存储协调器,并使用SQLite数据库做持久化存储

           NSPersistentStoreCoordinator *persistentStoreCoordinator =[[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:managedObjectModel];

           

           NSError *error = nil;

           NSPersistentStore *persistentStore = [persistentStoreCoordinatoraddPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrloptions:options error:&error];

 

           // 创建托管对象上下文

           if (persistentStore && !error)

           {

                NSManagedObjectContext*managedObjectContext = [[NSManagedObjectContext alloc] init];

                [managedObjectContextsetPersistentStoreCoordinator:persistentStoreCoordinator];

               

                self.objectContext =managedObjectContext;

           }

           else

           {

                NSLog(@"failed to addpersistent store with type to persistent store coordinator");

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

           }

       }

    }

   

   return self;

}

 

 

+ (CoreDataManager *)shareManager

{

   static CoreDataManager *staticCoreDataManager;

   static dispatch_once_t onceToken;

   

   dispatch_once(&onceToken, ^{

       staticCoreDataManager = [[self alloc] init];

       assert(staticCoreDataManager != nil);

   });

   

   return staticCoreDataManager;

}

 

-(id)createEmptyObjectWithEntityName:(NSString *)entityName

{

   NSManagedObject *managerObject = [NSEntityDescriptioninsertNewObjectForEntityForName:entityNameinManagedObjectContext:self.objectContext];

   return managerObject;

}

 

- (NSArray*)getListWithPredicate:(NSPredicate *)predicate sortDescriptors:(NSArray*)sortDescriptions entityName:(NSString *)entityName limitNum:(NSNumber*)limitNum

{

   NSError *error = nil;

   

   // 创建取回数据请求

   NSFetchRequest *fetchRequest = [NSFetchRequestfetchRequestWithEntityName:entityName];

   

    //设置查询条件

   [fetchRequest setPredicate:predicate];

   

   // 设置排序条件

   [fetchRequest setSortDescriptors:sortDescriptions];

   

   // 查询条件的总数

   [fetchRequest setFetchLimit:[limitNum intValue]];

   

   // 执行获取数据请求,返回数组

   NSArray *fetchResult = [self.objectContextexecuteFetchRequest:fetchRequest error:&error];

   

   return fetchResult;

}

 

- (BOOL)deleteObject:(NSManagedObject*)object

{

   [self.objectContext deleteObject:object];

   

   BOOL isSuccess = [self save];

   return isSuccess;

}

 

- (void)deleteObject:(NSManagedObject*)object complete:(void (^)(BOOL isSuccess))complete

{

   BOOL isSuccess = [self deleteObject:object];

   if (complete)

    {

       complete(isSuccess);

    }

}

 

-(BOOL)deleteAllObjectWithEntityName:(NSString *)entityName

{

   NSArray *allObjects = [self getListWithPredicate:nil sortDescriptors:nilentityName:entityName limitNum:nil];

   

   if (allObjects && 0 != allObjects.count)

    {

       for (NSManagedObject *object in allObjects)

       {

           [self.objectContext deleteObject:object];

       }

       

       BOOL isSuccess = [self save];

       return isSuccess;

    }

   

   return NO;

}

 

-(void)deleteAllObjectWithEntityName:(NSString *)entityName complete:(void(^)(BOOL isSuccess))complete

{

   BOOL isSuccess = [self deleteAllObjectWithEntityName:entityName];

   if (complete)

    {

       complete(isSuccess);

    }

}

 

- (BOOL)save

{

   NSError *error = nil;

   BOOL isSuccess = [self.objectContext save:&error];

   return isSuccess;

}

 

- (void)save:(void (^)(BOOLisSuccess))complete

{

   BOOL isSuccess = [self save];

   if (complete)

    {

       complete(isSuccess);

    }

}

 

@end

 

 

(2)调用封装类

导入头文件

#import "CoreDataManager.h"

#import "NameCache.h"

 

搜索/删除全部/删除指定/保存

- (void)search

{

   NSPredicate *predicate = [NSPredicate predicateWithFormat:@"cacheName== %@", @"zhangshaoyu"];

   

   NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]initWithKey:@"cacheTime" ascending:NO];

   NSArray *sortDescriptions = [[NSArray alloc]initWithObjects:sortDescriptor, nil];

   

   NSArray *array = [[CoreDataManager shareManager]getListWithPredicate:predicate sortDescriptors:sortDescriptionsentityName:@"NameCache" limitNum:[NSNumber numberWithInt:10]];

   

   NSLog(@"array %@", array);

   for (NameCache *cache in array)

    {

       NSString *name = cache.cacheName;

       NSString *key = cache.cacheKey;

       NSDate *date = cache.cacheTime;

       

       NSData *data = cache.cacheImage;

       

       NSLog(@"name = %@, key = %@, date = %@, data = %@", name, key,date, data);

    }

}

 

- (void)deleteAll

{

//   // 保存区域信息前先将已有信息删除,避免造成数据重复

//   [[CoreDataManager shareManager]deleteAllObjectWithEntityName:@"NameCache"];

   

   [[CoreDataManager shareManager]deleteAllObjectWithEntityName:@"NameCache" complete:^(BOOL isSuccess){

        NSLog(@"%@", [NSStringstringWithFormat:@"delete all:%@", (isSuccess ? @"success": @"failue")]);

   }];

}

 

- (void)delete

{

   // 删除某个

   NSPredicate *predicate = [NSPredicatepredicateWithFormat:@"cacheName == %@", @"zhangshaoyu"];

    NSSortDescriptor*sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"cacheTime"ascending:NO];

   NSArray *sortDescriptions = [[NSArray alloc]initWithObjects:sortDescriptor, nil];

   NSArray *array = [[CoreDataManager shareManager] getListWithPredicate:predicatesortDescriptors:sortDescriptions entityName:@"NameCache"limitNum:[NSNumber numberWithInt:10]];

   

   NSLog(@"array %@", array);

   for (NameCache *cache in array)

    {

       NSString *name = cache.cacheName;

       NSString *key = cache.cacheKey;

       NSDate *date = cache.cacheTime;

       

       NSData *data = cache.cacheImage;

       

       NSLog(@"name = %@, key = %@, date = %@, data = %@", name, key,date, data);

       

//       [[CoreDataManager shareManager] deleteObject:cache];

       

       [[CoreDataManager shareManager] deleteObject:cache complete:^(BOOLisSuccess) {

           NSLog(@"%@", [NSString stringWithFormat:@"deleteobject:%@", (isSuccess ? @"success" : @"failue")]);

       }];

    }

}

 

- (void)save

{

   NSArray *array = [NSArray arrayWithObjects:@"zhangshaoyu",@"herman", @"weishijiajie", nil];

   

   // 保存新信息

   for (NSInteger index = 0; index < array.count; index++)

    {

       NSString *name = array[index];

       NSString *key = [NSString stringWithFormat:@"%ld", index];

       

       NameCache *cache = [[CoreDataManager shareManager]createEmptyObjectWithEntityName:@"NameCache"];

       [cache setCacheName:name];

       [cache setCacheKey:key];

       [cache setCacheTime:[NSDate date]];       

       

       NSData *image = [[NSData alloc] initWithContentsOfURL:[NSURLURLWithString:@"http://gtb.baidu.com/HttpService/get?p=dHlwZT1pbWFnZS9qcGVnJm49dmlzJnQ9YWRpbWcmYz10YjppZyZyPTEzMjA2ODYxODAsMzY1MTE3NTc5MgAAAA=="]];

       [cache setCacheImage:image];

       

//       [[CoreDataManager shareManager] save];

       

       [[CoreDataManager shareManager] save:^(BOOL isSuccess) {

           NSLog(@"%@", [NSString stringWithFormat:@"saveobject:%@", (isSuccess ? @"success" : @"failue")]);

       }];

    }

}

 

 

五、说明

前面所提到的基本上是关于Core Data框架的入门。

Core Data还远不止这些功能,它还支持自动撤销机制,一对多关联等。

待续:自动撤销、关联、数据迁移、数据查看、第三方库使用……。

© 著作权归作者所有

laoyi007
粉丝 0
博文 34
码字总数 34280
作品 0
南京
私信 提问
Swift实践:使用CoreData完成上班签到小工具

image.png 之前在前两篇里面实现了一个十分简陋的通讯录,而且都是通过系统默认的方式创建的CoreData。可是实际中哪里有那么好的事情嘛,要是忘记在创建工程的时候勾选了下面这个图怎么办? ...

非典型技术宅
2017/12/03
0
0
基于Xcode8.x的CoreData的使用

首先说说对于CoreData的理解,类似于FMDB。他能将数据库中的列表转换成模型实体对象,方便开发者使用。同时,也能将一个将实体对象转换成数据库中的表,存储到数据库中。这就是CoreData,数据...

最牛逼的代码搬运工
2016/12/07
188
0
CoreData基本使用(更新:储存数组、字典类型)

前几天项目里面加入了CoreData,第一次用,记录一下,这里只记录创建项目之后添加的CoreData。 demo地址: CoreDataDemo 1. 创建CoreData模型文件 2. 创建项目中需要用到的实体(Entities),...

YvanLiu
2018/05/02
0
0
CoreData的简单使用

一.CoreData 1.CoreData用于做数据持久化,适合大数据量的存储和查询; 2.CoreData不是数据库,CoreData可以使用数据库,XML等方式来存储数据; 3.SQLite通过SQL语句操作数据,CoreData使用面...

鸡蛋炒青椒
2016/09/03
20
0
isunimp/ModelUtility

ModelUtility 强大的JSON和Model转换库,解决其他类似框架在Swift中使用CoreData的Crash问题以及解析不成功等问题,专注于为Swift提供一个强大且稳定的Model框架。 Features 支持在Swift中使...

isunimp
2016/05/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OpenStack 简介和几种安装方式总结

OpenStack :是一个由NASA和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项目。项目目标是提供实施简单、可大规模扩展、丰富、标准统一的云计算管理平台。OpenSta...

小海bug
今天
5
0
DDD(五)

1、引言 之前学习了解了DDD中实体这一概念,那么接下来需要了解的就是值对象、唯一标识。值对象,值就是数字1、2、3,字符串“1”,“2”,“3”,值时对象的特征,对象是一个事物的具体描述...

MrYuZixian
今天
6
0
数据库中间件MyCat

什么是MyCat? 查看官网的介绍是这样说的 一个彻底开源的,面向企业应用开发的大数据库集群 支持事务、ACID、可以替代MySQL的加强版数据库 一个可以视为MySQL集群的企业级数据库,用来替代昂贵...

沉浮_
今天
4
0
解决Mac下VSCode打开zsh乱码

1.乱码问题 iTerm2终端使用Zsh,并且配置Zsh主题,该主题主题需要安装字体来支持箭头效果,在iTerm2中设置这个字体,但是VSCode里这个箭头还是显示乱码。 iTerm2展示如下: VSCode展示如下: 2...

HelloDeveloper
今天
7
0
常用物流快递单号查询接口种类及对接方法

目前快递查询接口有两种方式可以对接,一是和顺丰、圆通、中通、天天、韵达、德邦这些快递公司一一对接接口,二是和快递鸟这样第三方集成接口一次性对接多家常用快递。第一种耗费时间长,但是...

程序的小猿
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部