iOS开发--数据库管理CoreData的使用

[原创文章,转载请提前说明并附上原文链接]
CoreData是iOS5后,苹果提供的原生的用于对象化管理数据并且持久化的框架。CoreData本质上是将底层数据库封装成对象进行管理。但数据库实际上只是CoreData的一个功能,并不是全部功能。在iOS开发中,除了可以使用CoreData进行数据管理,还可以使用SQLite进行内存管理。并且有封装好SQLite代码的OC框架FMDB给我们使用。具体看我上篇文章。SQLite重要框架FMDB的使用.但对比SQLite,CoreData有下面几个优势。第一是CoreData作为苹果提供的原生框架,在内存方法比SQLite有性能上的优势。第二是CoreData操作数据不需要使用SQLite代码,使用方便。第三是CoreData把数据用面向对象方式进行管理,操作数据库更方便。
CoreData的核心是Core Data stack(技术栈堆)。CoreData就是依靠Core Data stack中的几个对象进行数据操作的。这几对象是:
NSManagedObjectContext ,管理对象的上下文: 负责管理模型对象的一个集合,
NSManagedObjectModel 被管理的对象模型
NSPersistentStoreCoordinator 存储调度器: 负责将数据保存到磁盘,
NSPersistentStore用于保存模型数据,受NSPersistentStoreCoordinator 存储调度器的操控。
这三个对象的关系如下面图片所示,苹果官方给出了这几个对向关系的图解。简单理解起来就是最上面的NSManagedObjectContext负责管理对象模型。然后将管理的对象模型发送给NSPersistentStoreCoordinator 存储调度器,存储调度器通过NSPersistentStore操作SQLite语句,将数据持久化到本地,保存到StoryFile中。

Paste_Image.png

Paste_Image.png
Paste_Image.png

数据库的使用也很简单,我们只需要在创建项目文件的时候勾选使用coreData的选项,系统就会帮我们创建一个包含CoreData的项目文件。

Paste_Image.png

然后在界面上就会出现下面的变化。我们点击添加属性按钮,就能在数据库中给数据模型添加属性。

Paste_Image.png

添加完数据库后我们进行下面操作就能将数据模型转为代码文件。

Paste_Image.png

做完上面操作之后我们就能对数据库模型进行操作了。

Paste_Image.png

我们在操作数据,对数据进行增删改查的时候,都需要用到Core Data stack这个工具。我们自己可以封装一个Core Data stack,这样更能加深我们对Core Data stack这个工具的理解。
下面是封装一个工具类的代码:
首先是该工具类的.h文件中的代码


#import <Foundation/Foundation.h>

#import <CoreData/CoreData.h>

#define KXBCoreManagerInstance [HMCoreDataStackManager shareInstance]

@interface HMCoreDataStackManager : NSObject

///单例
+(HMCoreDataStackManager*)shareInstance;

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

///模型对象
@property(strong,nonatomic)NSManagedObjectModel *managerModel;

///存储调度器
@property(strong,nonatomic)NSPersistentStoreCoordinator *maagerDinator;

//保存数据的方法
-(void)save;

@end

然后是.m文件中的代码

#import "HMCoreDataStackManager.h"

@implementation HMCoreDataStackManager

///单例的实现
+(HMCoreDataStackManager*)shareInstance
{
  static HMCoreDataStackManager *instance = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    instance = [[HMCoreDataStackManager alloc]init];
  });
 
  return instance;
}

-(NSURL*)getDocumentUrlPath
{
 ///获取文件位置
 return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]
  ;
}

//懒加载managerContenxt
-(NSManagedObjectContext *)managerContenxt
{
  if (_managerContenxt != nil) {
   
    return _managerContenxt;
  }
 
  _managerContenxt = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSMainQueueConcurrencyType];
 
  ///设置存储调度器
  [_managerContenxt setPersistentStoreCoordinator:self.maagerDinator];

  return _managerContenxt;
}

///懒加载模型对象
-(NSManagedObjectModel *)managerModel
{
 
  if (_managerModel != nil) {
   
    return _managerModel;
  }
 
  _managerModel = [NSManagedObjectModel mergedModelFromBundles:nil];
 
  return _managerModel;
}

-(NSPersistentStoreCoordinator *)maagerDinator
{
  if (_maagerDinator != nil) {
   
    return _maagerDinator;
  }

  _maagerDinator = [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:self.managerModel];

  //添加存储器
  /**
  * type:一般使用数据库存储方式NSSQLiteStoreType
  * configuration:配置信息 一般无需配置
  * URL:要保存的文件路径
  * options:参数信息 一般无需设置
  */
 
  //拼接url路径
  NSURL *url = [[self getDocumentUrlPath]URLByAppendingPathComponent:@"sqlit.db" isDirectory:YES];
 
  [_maagerDinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:nil];

  return _maagerDinator;
}

-(void)save
{  ///保存数据
  [self.managerContenxt save:nil];
}

通过上面代码可以看出封装一个Core Data stack类并不是很难,我们需要做的是创建一个单例,然后懒加载一个NSManagedObjectContext,并给NSManagedObjectContext添加存储调度器NSPersistentStoreCoordinator。
懒加载存储调度器的时候给存储调度器添加存储器PersistentStore。在最后提供一个保存数据的方法,每次我们修改数据库中文件数据的时候,都需要用Core Data stack调用save方法保存数据。
CoreData关于数据的操作无非就是增删改查。增删改查我们同样需要使用自定义的Core Data stack工具类。
增加数据:

Person *p = [NSEntityDescription insertNewObjectForEntityForName:@"Person" in Managed ObjectContext : kManagedObjectContext.managedObjectContext];
 p.age = @(13);
 p.name = @"张三"; 
[kManagedObjectContext save];

删除数据:

//1.创建一个查询请求
 NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Person"]; 
//2.创建查询谓词(查询条件) 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@",@"张三"];
 //3.给查询请求设置谓词
 request.predicate = predicate; 
//4.查询数据
 NSArray<Person*> *arr = [kManagedObjectContext.managedObjectContext executeFetchRequest:request error:nil]; 
//5.删除数据
 [kManagedObjectContext.managedObjectContext deleteObject:arr.firstObject]; 
//6.同步到数据库 [kManagedObjectContext save];

修改数据:

//1.创建一个查询请求 
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Person"]; 
//2.创建查询谓词(查询条件) 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@",@"张三"];
 //3.给查询请求设置谓词
 request.predicate = predicate;
 //4.查询数据 
NSArray<Person*> *arr = [kManagedObjectContext.managedObjectContext executeFetchRequest:request error:nil]; 
//5.改变数据
 arr.firstObject.name = @"李四";
 arr.firstObject.age = @(18);
 //6.同步到数据库
 [kManagedObjectContext save];

查询数据:

//1.创建一个查询请求 
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Person"];
 //2.创建查询谓词(查询条件) 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@",@"张三"]; 
//3.给查询请求设置谓词 
request.predicate = predicate; 
//4.查询数据 
NSArray<Person*> *arr = [kManagedObjectContext.managedObjectContext executeFetchRequest:request error:nil]; NSLog(@"%@====%@",arr.firstObject.name,arr.firstObject.age);

使用CoreData我们可以轻松实现很多数据的操作,例如通讯录数据录的增删改查。
在这里提供一个通讯录数据操作的demo,使用CoreData,我们能轻松地实现通讯录功能。
CoreData实现通讯录

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

推荐阅读更多精彩内容