CoreData数据库的基本使用

一、CoreData介绍

CoreData是苹果公司封装的数据持久化框架。说白了就是对SQLite进行的封装 CoreData在iOS 3.0中开始开放, 它允许用户按照实体-属性-值模型组织数据,数据最终的存储形式可以是:二进制、XML、SQLite数据库、内存里、活自定义数据类型
如果要了解SQLite的的使用可以参阅博客 :http://www.jianshu.com/p/0b9b78e704a4
CoreData的优势
1 它是苹果公司原生态的产品。
2 它可以节省代码量 大概是30%-70%。
3 它支持可视化建模。
4 CoreData支持数据库版本升级

CoreData的构成
(1)NSManagedObjectContext 被管理者对象上下文 相当于一个临时数据库 我们存储或者查询都是通过这个对象来的
(2)NSManagedObjectModel 被管理对象模型,可以简单的理解为可视化建模文件 我们在可视化建模中是Entity自动生成model 方便让文件存储助理来进行管理
(3)NSPersistentStoreCoordinator 文件存储助理,相当于数据库的链接器,它是CpreData的核心 他负责链接所有的模块 包括真实的存储文件
(4)NSManagedObject 被管理的数据记录, 相当于数据库中的表格记录
(5)NSFetchRequest 获取数据的请求,相当于SQL语句
(6)NSEntityDescription 实体结构,相当于表结构
(7)后缀为.xcdatamodeld的包 里面是.xcodemodel文件 用数据模型编辑器编译。编译后为.momd或.mom文件

二、使用简介

我们创建一个工程,在创建的时候选择使用 Core Data



在AppDelegate里面会相比不使用CoreData多出来几个属性和方法 在以下代码中都加了非常详细的代码

#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
//被管理对象上下文,相当于一个临时数据库 我们存储或者查询都是通过这个对象来的
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
//被管理对象模型,可以简单的理解为可视化建模文件 我们在可视化建模中是Entity自动生成model 方便让文件存储助理来进行管理
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
//文件存储助理,他是CpreData的核心 他负责链接所有的模块 包括真实的存储文件
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
//将我们在内存中的操作进行持久化
- (void)saveContext;
//获取真实文件的路径
- (NSURL *)applicationDocumentsDirectory;
@end

紧接着我们在点击后缀为.xcdatamodeld



接下来 并根据提示做如下操作



点击create

那么在我们的工程中就出现了类似下图的几个文件 我们在使用的时候直接引入头文件就可以Student.h或者Person.h就可以了


三、增、删、改、查的实现

接下来我们来实现什么功能呢?请看下图



我们创建一个类CoreDataTableViewController 继承自UITableViewController

.h
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
@interface CoreDataTableViewController : UITableViewController
//创建一个上下文对象 用于处理所有与存储相关的请求
@property(nonatomic,strong)NSManagedObjectContext *myContext;
//创建一个数组用于存储数组的数据源
@property(nonatomic,strong)NSMutableArray *allData;
@end

.m
- (void)viewDidLoad {
    [super viewDidLoad];
    //进行数据初始化
    AppDelegate *delegate= [UIApplication sharedApplication].delegate;
    self.myContext = delegate.managedObjectContext;
    self.allData = [NSMutableArray array];
    //通过coreData读取本地所有的数据
    [self getAllDataFromCoreData];
}

1、增加

- (IBAction)addData:(id)sender {
    //创建student对象
    NSEntityDescription *description = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:_myContext];
  
    Student *student = [[Student alloc]initWithEntity:description insertIntoManagedObjectContext:_myContext];
    
    //给属性赋值
    student.name = @"张三";
    student.age = arc4random()%73+1;

    //修改数据源
    [_allData addObject:student];
    
    //修改界面
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.allData.count -1 inSection:0];
    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
    //将数据保存到文件中进行持久化 
/*
//    NSError *error = nil;
//    [self.myContext save:&error];
//    
//    if (nil != error) {
//        NSLog(@"数据持久化存在问题");
//    }
*/  
//等同于以上实例持久化方式
    [(AppDelegate *)[UIApplication sharedApplication].delegate saveContext];
}

2、删除

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        
        //获取当前cell代表的数据
        Student *stu = _allData[indexPath.row];
        
        //修改数据源
        [self.allData removeObject:stu];
        
        //更新UI
        [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
        
        //将临时数据库里进行删除并进行本地持久化
        [self.myContext deleteObject:stu];
        
        [self.myContext save:nil];
    }
}

3、修改

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:_myContext];
    [fetchRequest setEntity:entity];

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"age"
                                                                   ascending:YES];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]];
    NSError *error = nil;
    NSArray *fetchedObjects = [_myContext executeFetchRequest:fetchRequest error:&error];
    if (fetchedObjects != nil) {
        //修改对应的数据
        Student *stu = fetchedObjects[indexPath.row];
        stu.name = @"尼古拉斯&赵四";
        //更新数据源
        [self.allData removeAllObjects];
        [self.allData addObjectsFromArray:fetchedObjects];   
        //更新界面
        [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft]; 
        //将修改本地持久化
        [self.myContext save:nil];
    }
}

4、查询

-(void)getAllDataFromCoreData{
    
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:_myContext];
    [fetchRequest setEntity:entity];
    // Specify criteria for filtering which objects to fetch
    
    //排序条件
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"age" ascending:YES];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]];
    
    NSError *error = nil;
    NSArray *fetchedObjects = [_myContext executeFetchRequest:fetchRequest error:&error];
    if (fetchedObjects == nil) {
        NSLog(@"两手空空,你让伦家盆满钵满");
    }
    //将查询到的数据添加到数据源
    [self.allData addObjectsFromArray:fetchedObjects];
    //重新加载tableView
    [self.tableView reloadData];
}

四、关系建立

实际我们在项目中建立起来的模型对象并不是孤立存在的例如:Company(公司) 和 Employee(雇员)之间是存在归属关系的 我们就依此为例
首先我们创建两个模型对象 Company 和 Employee



那么我们如何建立起公司和职员之间的链接呢?往下看



代码实例如下:
#import "ViewController.h"
#import "Company.h"
#import "Employee.h"
#import "AppDelegate.h"
@interface ViewController ()
@property(nonatomic,strong)NSManagedObjectContext *myContext;
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.myContext = ((AppDelegate *)[UIApplication sharedApplication].delegate).managedObjectContext;
    Company *company = [[Company alloc]initWithEntity:[NSEntityDescription entityForName:@"Company" inManagedObjectContext:self.myContext] insertIntoManagedObjectContext:self.myContext];
    company.name = @"网易新闻";
    company.address = @"中关村东路1号院清华科技园D座";
    Employee *emp1 = [[Employee alloc]initWithEntity:[NSEntityDescription entityForName:@"Employee" inManagedObjectContext:self.myContext] insertIntoManagedObjectContext:self.myContext];
    emp1.name = @"赵二";
    emp1.age =21;
    Employee *emp2 = [[Employee alloc]initWithEntity:[NSEntityDescription entityForName:@"Employee" inManagedObjectContext:self.myContext] insertIntoManagedObjectContext:self.myContext];
    emp2.name = @"见哥";
    emp2.age = 22;
    [company addBelongObject:emp1];
    [company addBelongObject:emp2];
    [self.myContext save:nil];
    #pragma mark ------模拟读取查询
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Company" inManagedObjectContext:self.myContext];
    [fetchRequest setEntity:entity];
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]];
    NSError *error = nil;
    NSArray *fetchedObjects = [self.myContext executeFetchRequest:fetchRequest error:&error];
    if (fetchedObjects == nil) {
        NSLog(@"两手空空,大变活人");
    }
    Company *com =fetchedObjects[0];
    //这里我们知道只是存了一个
    NSLog(@"%@--%@",com.name,com.address);
    for (Employee *em in com.belong) {
        NSLog(@"name:%@,age = %d",em.name,em.age);
    }
}

五、数据库版本升级

实际上开发过程中数据库的版本升级也是很常见的 怎么实现呢?在这里直接上图 简单明了



这时候我们多了新的.xcdatamodeld文件 绿色对勾表示当前选择数据库NSManagedObjectModel




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

推荐阅读更多精彩内容