美文网首页
08、CoreData的简单应用

08、CoreData的简单应用

作者: 深爱久随i | 来源:发表于2017-01-20 10:18 被阅读0次

    一、CoreData数据库框架的优势

    1、CoreData历史
    CoreData数据持久化框架是Cocoa API的一部分,他允许按照实体-属性-值模型组织数据,并以XML、二进制文件或者SQLite数据文件的格式持久化数据,主要提供对象-关系映射(ORM)功能,把OC对象转换为数据保存在文件中,也可以将数据转换为OC对象。
    2、sqlite与CoreData的区别
    sqlite:

    • 基于C接口,需要使用sql语句,代码繁琐
    • 在处理大量数据时,表关系更在直接
    • 在OC中不是可视化的
      CoreData:
    • 可视化,有undo/redo能力
    • 可以实现多种文件格式NSSQLiteStoreType、NSBinaryStoreType、NSInMemoryStoreType、NSXMLStoreType
    • 苹果官方API支持,与iOS结合更紧密
      3、CoreData核心对象
      实体管理类:NSManagedObject
      实体描述类:NSEntityDescription
      数据管理器类:NSManagedObjectContext
      数据连接器类:NSPersistentStoreCoordinator
      数据模型器类:NSManagedObjectModel


      CoreData.png
    CoreData的存储过程:

    被管理对象的上下文(NSManagedObjectContext)将被管理的对象(NSManagedObject)交给持久化数据助理(NSPersistentStoreCoordinator),持久化数据助力将被管理对象转换为数据文件(XML,SQLite,Binary)存储到文件系统中(FileSystem)

    读取过程:

    助理从文件系统中读取出数据文件,将数据文件转换为被管理的对象交给context操作

    二、CoreData的使用

    1、创建工程
    一定要勾选下面的Use Core Data


    Core_Data.png

    2、进入工程就可以看见多了一个文件
    点击下方的Add Entity➕就可以添加实体类
    使用Attributes选项下的+ -号可以给表添加和删除字段
    在Relationships下面可以添加表之间的关系

    屏幕快照 2017-01-20 上午10.05.33.png

    3、建一个实体类
    选择Core Data 下的NSManagedObject subclass文件新建,一直点next,选择要新建的model,选择新建类的实体。
    Use scalar properties for primitive data types选项,如果勾选,数据库中的integer类型就在类中变成int,不勾选,就变成NSNumber


    ![屏幕快照 2017-01-20 上午10.09.06.png](https://img.haomeiwen.com/i2758407/b62255ff114bbfe0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    4、这时就会产生四个类


    屏幕快照 2017-01-20 上午10.10.39.png

    这时我们就可以对学生这张表进行增删改查的操作了

    @implementation ViewController
    //该方法是用来获取AppDelegate对象
    -(AppDelegate*)appDalegate{
        return (AppDelegate*)[UIApplication sharedApplication].delegate;
    }
    
    //获取上下文,对数据对象进行操作
    -(NSManagedObjectContext*)managedObjectContext{
        return [self appDalegate].managedObjectContext;
    }
    
    //增加数据
    -(void)addData{
        //创建需要增加的数据对象
        //第一个参数:实体名称,表名
        //第二个参数:该数据被哪个context操作
        Student* stu_1=[NSEntityDescription insertNewObjectForEntityForName:@"Student" inManagedObjectContext:[self managedObjectContext]];
        stu_1.name = @"余菲";
        stu_1.age = @18;
        //将增加操作同步到底层
        [[self appDalegate] saveContext];
        
    }
    
    //读取
    -(void)queryData{
       //创建要被读取的实体对象
        //第一个参数:实体类的名称
        //第二个参数:所在的上下文
        NSEntityDescription* studentEntity = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:[self managedObjectContext]];
        //创建查询请求对象
        NSFetchRequest* fetch=[[NSFetchRequest alloc] init];
        //设置该请求要查询的实体对象
        [fetch setEntity:studentEntity];
        //开始查询
        //返回值为数组,数组中的元素就是该实体类对应的的类型对象
        NSArray* array=[[self managedObjectContext] executeFetchRequest:fetch error:nil];
        //遍历数组,取出对象
        for (Student* student in array) {
            NSLog(@"name=%@,age=%@",student.name,student.age);
        }
        
    }
    
    //更新操作
    -(void)updateData{
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:[self managedObjectContext]];
        [fetchRequest setEntity:entity];
        // Specify criteria for filtering which objects to fetch
        //谓词,查询条件  相当于sql语句中的where
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@", @"余菲"];
        [fetchRequest setPredicate:predicate];
        // Specify how the fetched objects should be sorted
        //按照哪个属性进行排序
        //key:排序条件的属性名
        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name"ascending:YES];
        [fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]];
        
        NSError *error = nil;
        NSArray *fetchedObjects = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
        //    if (fetchedObjects == nil) {
        //
        //    }
        if (fetchedObjects.count) {              
            //更新操作
            for (Student* student in fetchedObjects) {
                student.age=@20;
                
            }
        }
        //对CoreData存储的内容进行了修改,必须进行同步操作
        [[self appDalegate] saveContext];
        
    
    }
    
    //删除操作
    -(void)removeData{
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:[self managedObjectContext]];
        [fetchRequest setEntity:entity];
        // Specify criteria for filtering which objects to fetch
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@ && age = %@", @"余菲",@18];
        [fetchRequest setPredicate:predicate];
        // Specify how the fetched objects should be sorted
        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name"
                                                                       ascending:YES];
        [fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]];
        
        NSError *error = nil;
        NSArray *fetchedObjects = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
        if (fetchedObjects != nil) {
            for (Student* student in fetchedObjects) {
                //删除操作
                [[self managedObjectContext] deleteObject:student];
            }
            
        }else{
            NSLog(@"未找到");
        }
        
        [[self appDalegate] saveContext];
        
    }
    
    //非底层的数据对象的所有操作都是通过上下文完成的
    - (void)viewDidLoad {
        [super viewDidLoad];
    //    [self addData];//增加数据
    //      [self updateData];
          [self queryData];
        [self removeData];
       
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
       
    }
    
    @end
    
    

    在这里,大家可以简单的使用CoreData进行一个学生列表的管理
    1.建一个TableView

    #import "StudentVC.h"
    #import "Android.h"
    #import "AppDelegate.h"
    @interface StudentVC ()<UITableViewDataSource,UITableViewDelegate>
    @property (weak, nonatomic) IBOutlet UITableView *tableView;
    
    @property(nonatomic,strong)NSMutableArray* allDataMArray;//存放所有数据
    @end
    
    @implementation StudentVC
    
    //_allDataMArray的懒加载
    -(NSMutableArray*)allDataMArray{
        if (!_allDataMArray) {
            
            _allDataMArray=[[NSMutableArray alloc] init];
        }
        
        return _allDataMArray;
    }
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.automaticallyAdjustsScrollViewInsets=NO;
        [self insertData];//插入操作
        [self queryData];//查询操作
    }
    
    //返回行数
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
        return self.allDataMArray.count;
    }
    
    //定义单元格
    -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        UITableViewCell* cell=[tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
        Android* android=self.allDataMArray[indexPath.row];
        cell.textLabel.text=android.name;
        cell.detailTextLabel.text=android.sex;
        cell.imageView.image=[UIImage imageWithData:android.headImg];
        return cell;
        
    }
    
    
    //获取appDelegate
    -(AppDelegate*)appDelegate{
        return (AppDelegate*)[UIApplication sharedApplication].delegate;
    }
    
    //获取managedContext
    -(NSManagedObjectContext*)managedContext{
        return [self appDelegate].managedObjectContext;
    }
    
    //首次运行应用程序的时候,插入全班同学的数据·,再次打开时,就不进行插入操作了
    -(void)insertData{
        //首次启动的时候,由于我们没有存储值,所以获取到的值为NO。当我们启动之后就将该值置为YES,
        //isFirst==NO 说明首次启动  若等于YES  就不是首次启动
        BOOL isFirst=[[NSUserDefaults standardUserDefaults] boolForKey:@"isFirst"];
        if (isFirst) {
            return;
        }
        //不进if分支,说明是首次启动
         NSDictionary* dic_1=@{@"name":@"王翰",@"sex":@"男"};
         NSDictionary* dic_2=@{@"name":@"李博",@"sex":@"男"};
         NSDictionary* dic_3=@{@"name":@"雷龙飞",@"sex":@"男"};
         NSDictionary* dic_4=@{@"name":@"樊李鹏",@"sex":@"男"};
         NSDictionary* dic_5=@{@"name":@"张泽安",@"sex":@"男"};
         NSDictionary* dic_6=@{@"name":@"刘元",@"sex":@"男"};
         NSDictionary* dic_7=@{@"name":@"李豫君",@"sex":@"男"};
         NSDictionary* dic_8=@{@"name":@"李雄飞",@"sex":@"男"};
         NSDictionary* dic_9=@{@"name":@"任涛",@"sex":@"男"};
        NSDictionary* dic_10=@{@"name":@"薛佳伟",@"sex":@"男"};
        NSDictionary* dic_11=@{@"name":@"余菲",@"sex":@"女"};
        NSArray* array=@[dic_1,dic_2,dic_3,dic_4,dic_5,dic_6,dic_7,dic_8,dic_9,dic_10,dic_11];
        
        for (NSDictionary* item in array) {
             Android* android=[NSEntityDescription insertNewObjectForEntityForName:@"Android" inManagedObjectContext:[self managedContext]];
            android.name=item[@"name"];
            android.sex=item[@"sex"];
            UIImage* headImg=[UIImage imageNamed:@"10.JPG"];
            android.headImg=UIImagePNGRepresentation(headImg);
           
        }
       
        //进行同步操作
        [[self appDelegate] saveContext];
        //将isFirst置为YES下次就不会增加数据了
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"isFirst"];
        
        
    }
    
    //查询操作
    -(void)queryData{
       //需要被查询的实体对象,它是通过实体描述类来获取的
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Android" inManagedObjectContext:[self managedContext]];
        //需要查询请求对象
         NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        //为查询请求对象设置实体对象
        [fetchRequest setEntity:entity];
        //通过上下文发起获取数据的请求,返回值为数组类型
        NSArray* array=[[self managedContext] executeFetchRequest:fetchRequest error:nil];
        if (array&&array.count) {
            [self.allDataMArray addObjectsFromArray:array];
            
        }
        
    
        
       }
    
    //返回行高
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
        return 100;
    }
    
    //删除操作
    -(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
        
        //先删除数据,再删除单元格,因为删除单元格的时候会执行代理方法,会执行代理方法;如果我们先删除单元格,执行代理方法的时候,数据和单元格的个数就不匹配了,就有可能崩溃
        if (editingStyle==UITableViewCellEditingStyleDelete) {
            //当我们对数据做了持久化之后,先删除数据库或者coreData中的数据,再删除本地集合中的数据
            Android* android=[self.allDataMArray objectAtIndex:indexPath.row];
            //删除coreData中的数据
            [[self managedContext] deleteObject:android];
            //同步操作
            [[self appDelegate] saveContext];
            //删除了可变数组中的数据
            [self.allDataMArray removeObjectAtIndex:indexPath.row];
            //删除单元格,执行tableView的代理方法
            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:(UITableViewRowAnimationLeft)];
    
        }
        
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    /*
    #pragma mark - Navigation
    
    // In a storyboard-based application, you will often want to do a little preparation before navigation
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
        // Get the new view controller using [segue destinationViewController].
        // Pass the selected object to the new view controller.
    }
    */
    
    @end
    
    

    运行结果如下:


    屏幕快照 2017-01-20 上午10.14.56.png ![屏幕快照 2017-01-20 上午10.15.23.png](https://img.haomeiwen.com/i2758407/9556cd20009016dd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    今天的内容就完啦😝😝😝

    相关文章

      网友评论

          本文标题:08、CoreData的简单应用

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