zoukankan      html  css  js  c++  java
  • 项目开发--------CoreData 数据库

    一.CoreData介绍

    简介

      Core Data是iOS5之后才出现的一个框架,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象。在此数据操作期间,我们不需要编写任何SQL语句,这个有点类似于著名的Hibernate持久化框架,不过功能肯定是没有Hibernate强大的。简单地用下图描述下它的作用:

    abc

    左边是关系模型,即数据库,数据库里面有张person表,person表里面有id、name、age三个字段,而且有2条记录;

    右边是对象模型,可以看到,有2个OC对象;

    利用Core Data框架,我们就可以轻松地将数据库里面的2条记录转换成2个OC对象,也可以轻松地将2个OC对象保存到数据库中,变成2条表记录,而且不用写一条SQL语句。

    模型文件

      在Core Data,需要进行映射的对象称为实体(entity),而且需要使用Core Data的模型文件来描述app中的所有实体和实体属性。这里以Person(人)和Card(身份证)2个实体为例子,先看看实体属性和实体之间的关联关系:
    abc
    Person实体中有:name(姓名)、age(年龄)、card(身份证)三个属性
    Card实体中有:no(号码)、person(人)两个属性

    接下来看看创建模型文件的过程:
    1.选择模板
    abc

    abc

    2.添加实体


    3.添加Person的2个基本属性


    4.添加Card的1个基本属性



    5.建立Card和Person的关联关系

      

          

    右图中的表示Card中有个Person类型的person属性,目的就是建立Card跟Person之间的一对一关联关系(建议补上这一项),在Person中加上Inverse属性后,你会发现Card中Inverse属性也自动补上了



     了解NSManagedObject

    1.通过Core Data从数据库取出的对象,默认情况下都是NSManagedObject对象
     

    2.NSManagedObject的工作模式有点类似于NSDictionary对象,通过键-值对来存取所有的实体属性

    1> setValue:forKey:存储属性值(属性名为key)

    2> valueForKey:获取属性值(属性名为key)

    CoreData中的核心对象



    注:黑色表示类名,红色表示类里面的一个属性
    开发步骤总结:
    1.初始化NSManagedObjectModel对象,加载模型文件,读取app中的所有实体信息
    2.初始化NSPersistentStoreCoordinator对象,添加持久化库(这里采取SQLite数据库)
    3.初始化NSManagedObjectContext对象,拿到这个上下文对象操作实体,进行CRUD操作

    AppDelegate.m文件 注意这点代码是在创建工程时(勾选上CoreData后)自动带上的,不用自己写,只需注意一下个部分的功能即可,提示:数据库版本迁移时也在这里进行,已经用红色标注,

    //采用的是栈同步方式  中间有个临时存储器
    #pragma mark - Core Data stack
    //managedObjectContext  托管上下文(上下都管)对象  可以进行增,删,改,查
    @synthesize managedObjectContext = _managedObjectContext;
    //managedObjectModel 管理对象模型 将工程里的所有模型文件合并(为了以后方便生成数据库中的表)
    //
    @synthesize managedObjectModel = _managedObjectModel;
    //持久化存储协调器  实际操作由它来完成
    @synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
    //NSPersistentStore 持久化存储对象
    //NSManagedObject  管理对象(所谓的 model类 如:student.)
    
    
    - (NSURL *)applicationDocumentsDirectory {
        // The directory the application uses to store the Core Data store file. This code uses a directory named "com.----.CoredateDemo" in the application's documents directory.
    
            NSLog(@"%@",[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].lastObject);
    
        //在splite中,路径为字符串类型 ,  在coreData中路径为URL
        return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
      
    }
    
    
    #pragma mark ---获取管理对象模型
    - (NSManagedObjectModel *)managedObjectModel {
        // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
        if (_managedObjectModel != nil) {
            return _managedObjectModel;
        }
        //管理对象模型文件                              //与数据库文件名要对应
        NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"];
        _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
        return _managedObjectModel;
    }
    
    #pragma mark ---获取持久化存储协调器
    - (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
        // The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it.
        if (_persistentStoreCoordinator != nil) {
            return _persistentStoreCoordinator;
        }
        
        // Create the coordinator and store
        
        _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
        //存储文件名
        NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoredateDemo.sqlite"];
        NSError *error = nil;
        NSString *failureReason = @"There was an error creating or loading the application's saved data.";
        //options 版本迁移时使用
    #pragma mark ---NSString * const NSMigratePersistentStoresAutomaticallyOption  NSInferMappingModelAutomaticallyOption  两个方法一起用 支持版本迁移
    
        if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:@{ NSMigratePersistentStoresAutomaticallyOption:@YES , NSInferMappingModelAutomaticallyOption:@YES} error:&error]) {
            // Report any error we got.
            NSMutableDictionary *dict = [NSMutableDictionary dictionary];
            dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
            dict[NSLocalizedFailureReasonErrorKey] = failureReason;
            dict[NSUnderlyingErrorKey] = error;
            error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
            // Replace this with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
        
        return _persistentStoreCoordinator;
    }
    
    #pragma mark--获取管理对象上下文
    - (NSManagedObjectContext *)managedObjectContext {
        // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
        if (_managedObjectContext != nil) {
            return _managedObjectContext;
        }
        
        NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
        if (!coordinator) {
            return nil;
        }
        _managedObjectContext = [[NSManagedObjectContext alloc] init];
        [_managedObjectContext setPersistentStoreCoordinator:coordinator];
        return _managedObjectContext;
    }
    
    #pragma mark - Core Data Saving support
    
    
    //存储
    - (void)saveContext {
        NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
        if (managedObjectContext != nil) {
            NSError *error = nil;
            if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
                // Replace this implementation with code to handle the error appropriately.
                // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
                abort();
            }
        }
    }

    这是基本环境的配置,包括Core Date数据库的建立,以及相关两个类的建立

    ViewController.m
    #import "ViewController.h"
    #import "AppDelegate.h"
    #import "Person.h"
    #import "Car.h"
    
    @interface ViewController ()
    
    //管理对象上下文  负责所有与数据有关的类似于_bd(数据库连接对象)
    @property(nonatomic,strong)NSManagedObjectContext *manageObjectContext;
    
    @end
    
    @implementation ViewController
    
    //懒加载   注意要用self调用
    #warning 懒加载要用self.进行调用********懒加载中不能使用self
    -(NSManagedObjectContext *)manageObjectContext
    {
      //因为管理上下文对象的getter方法 在appdelegate中 所以先要获取appdelegate对象
        if (_manageObjectContext == nil) {
            //获取AppDelegate对象
          AppDelegate *delegate =  [UIApplication sharedApplication].delegate;
            _manageObjectContext = delegate.managedObjectContext;
        }
    
        return _manageObjectContext;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        [self addPerson];
        
    //    [self removePerson];
    //    [self update];
        
        [self selectAllPerson];
    }

    核心代码区:对于Core Data数据库的增删改查.

    CoreData数据库的增添

    #pragma mark ---增
    //添加一个person对象
    
    -(void)addPerson
    {
      //1.实例化一个person对象 ,并让context准备将person对象添加到数据库里面
        //注意.在coredata实例化一个对象需要使用实体描述
        
    #warning 懒加载要用self.进行调用********
        //第一种方式实例化对象
        Person *p1 = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.manageObjectContext];//懒加载要用self.进行调用********
       
    //    //第二种方式 创建实体描述对象
    //    NSEntityDescription  *personED = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:self.manageObjectContext];
    //    //根据实体描述对象创建person]对象
    //    Person *p1  =[[Person alloc]initWithEntity:personED insertIntoManagedObjectContext:self.manageObjectContext];
        
        
        //设置p1的属性信息
        p1.name = @"张三";
        p1.age = @18;
    //  p1.age = [NSNumber numberWithInteger:18];
        p1.phoneNum = @"456560";
        p1.headImage = UIImagePNGRepresentation([UIImage imageNamed:@"btn_02"]);
     
        //创建一个car对象
        Car *car1 = [NSEntityDescription insertNewObjectForEntityForName:@"Car" inManagedObjectContext:self.manageObjectContext];
        car1.brand = @"保时捷";
        car1.price = @123344666;
        car1.color = @"黄色";
    //    //将car对象添加到集合中
    //    NSSet *carSet = [NSSet setWithObjects:car1, nil];
    //    p1.cars = carSet;
        
        Car *car2 = [NSEntityDescription insertNewObjectForEntityForName:@"Car" inManagedObjectContext:self.manageObjectContext];
        car2.brand = @"宝马X7";
        car2.price = @123344666;
        car2.color = @"红色";
        //将car对象添加到集合中
        NSSet *carSet = [NSSet setWithObjects:car1,car2, nil];
        p1.cars = carSet;
        
        
        //3.person保存到数据库中
       BOOL flag =  [_manageObjectContext save:nil];
        if (flag) {
            NSLog(@"插入数据成功");
        }  else{
          NSLog(@"插入数据失败");
        
        }
    
    }

    CoreData数据库的删除

    #pragma mark ---删
    -(void)removePerson
    {
      //1.实例化查询请求
        NSFetchRequest  *request = [NSFetchRequest fetchRequestWithEntityName:@"Person"];
        //2.设置查询条件  (谓词条件---筛选)
        request.predicate = [NSPredicate predicateWithFormat:@"name = '张三'"];
        //3.(由管理对象上下文执行查询)根据查询条件执行查询
        NSArray *result = [self.manageObjectContext executeFetchRequest:request error:nil];
    
       //删除结果
        for (Person *person in result) {
            NSLog(@"%@ %@ %@",person.name,person.age,person.phoneNum);
            //从数据库中删除一条记录
    #warning 删除语句要记清楚------delete:person
            [self.manageObjectContext deleteObject:person];
            
        }
    
         //5.同步保存数据
        if ([_manageObjectContext save:nil]) {
            NSLog(@"删除成功");
        } else{
         NSLog(@"删除失败");
        
        }
    }

    CoreData数据库的更改

    #pragma mark ---改
    
    -(void)update
    {
       //1.实例化查询请求
        NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Car"];
        
        //2.设置查询条件                                      //拼写注意,细心
        request.predicate = [NSPredicate predicateWithFormat:@"brand CONTAINS '宝马X7'"];
        
        //3.由管理上下文对象 按照查询条件执行查询
       NSArray *result =  [self.manageObjectContext executeFetchRequest:request error:nil];
        
        for (Car *car in result) {
            NSLog(@"%@  %@ %@",car.brand,car.price,car.color);
            //更改车的品牌
            car.brand = @"宝马X5";
            
        }
      //5.数据同步
        if ([_manageObjectContext save:nil]) {
            
            NSLog(@"更新成功");
        }  else{
        
        NSLog(@"更新失败");
        
        }
    
    }

    CoreData数据库的查询

    #pragma mark ---查
    
    -(void)selectAllPerson
    {
      //1.实例化查询请求
        NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Person"];
        
        //2.设置排序
        NSSortDescriptor *sort  = [[NSSortDescriptor alloc] initWithKey:@"age" ascending:YES];
        
        request.sortDescriptors = @[sort];
        
        //3.设置帅选条件
       NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age < 20 && name  LIKE '*三'"];
        
        request.predicate = predicate;
        
        
        //4.由管理上下文对象 执行查询对象 执行查询
        
      NSArray *result =   [self.manageObjectContext executeFetchRequest:request error:nil];
        
        for (Person *person in result) {
            NSLog(@"%@%@%@",person.name,person.age,person.phoneNum);
        }
       
    
    }
  • 相关阅读:
    QuartusII13.0使用教程详解(一个完整的工程建立)
    基于Vivado调用ROM IP core设计DDS
    FPGA学习之路——一路走来
    基于basys2用verilog设计多功能数字钟(重写)
    基于basys2驱动LCDQC12864B的verilog设计图片显示
    PWM(脉宽调制)——LED特效呼吸灯设计
    Isim你不得不知道的技巧(整理)
    ISE、vivado、QuartusII调用notepad++、UE汇总(整理)
    java环境配置为1.7jdk为什么cmd java -version查看版本是1.8
    TCP/IP三次握手和HTTP过程
  • 原文地址:https://www.cnblogs.com/erdeng/p/4905257.html
Copyright © 2011-2022 走看看