CoreData数据库的基本使用

作者: 见哥哥长高了 | 来源:发表于2016-03-07 19:44 被阅读1181次

    一、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的基本用法。

    相关文章

      网友评论

      本文标题:CoreData数据库的基本使用

      本文链接:https://www.haomeiwen.com/subject/swoakttx.html