iOS - CoreData 数据库存储

简介: 1、CoreData 数据库CoreData 是 iOS SDK 里的一个很强大的框架,允许程序员以面向对象的方式储存和管理数据。使用 CoreData 框架,程序员可以很轻松有效地通过面向对象的接口管理数据。

1、CoreData 数据库

  • CoreData 是 iOS SDK 里的一个很强大的框架,允许程序员以面向对象的方式储存和管理数据。使用 CoreData 框架,程序员可以很轻松有效地通过面向对象的接口管理数据。CoreData 框架提供了 对象 - 关系映射 (ORM) 的功能,即能够将 OC 对象转化成数据,保存在 SQLite3 数据库文件中,也能够将保存在数据库中的数据还原成 OC 对象,在数据操作过程中,无需编写任何 SQL 语句。

    CoreData1

  • 模型文件及实体(Entity)。要使用 CodeData,首先需要定义模型文件,描述应用程序中的所有实体(Entities),所谓实体是跟数据库进行映射的对象。

    CoreData2

  • NSManagedObject:对应数据库中的一条记录。

    CoreData14

  • CoreData 主要对象关系示意图类似于数据库的句柄,handle,用来操纵数据库 持久化存储调度者,是数据库与对象之间的,在开发中。只会用到一次,如果不理解,直接粘代码。

    CoreData15

    CoreData16

    CoreData17

  • CoreData 主要对象

    • NSManagedObjectContext:负责应用和数据库之间的交互 (CRUD)。
    • NSPersistentStoreCoordinator:添加持久化存储库(如 SQLite 数据库), 是物理数据存储的物理文件和程序之间的联系的桥梁 ,负责管理不同对象上下文。
    • NSManagedObjectModel:被管理的对象模型。
    • NSEntityDescription:实体描述。

      CoreData18

2、CoreData 的使用

  • 配置

    • 1、在工程中新建 Data Model 数据模型文件。

      CoreData3

      CoreData4

    • 2、在 Data Model 模型文件中添加 Entity 实体,修改实体名称,并在实体中添加模型属性。

      CoreData5

    • 3、在模型文件右侧属性列表的 Code Generation 中设置生成 NSManagedObject subclass 子类的使用语言。

      CoreData6

    • 4、在模型文件右侧属性列表的 Class => Codegen 中设置 Manual/None。如果不修改此项程序编译时会报 Linker command failed with exit code 1 (use -v to see invocation) 错误。

      CoreData7

    • 5、基于 Data Model 数据库文件中的 Entity 创建 NSManagedObject subclass 类。Xcode8 从系统菜单的 Editor 创建,创建后文件中多出来 4 个文件。

      CoreData8

      CoreData9

      CoreData10

      CoreData11

    • 6、在需要使用 CoreData 的文件中。

          // 引入头文件
          #import "Student+CoreDataClass.h"
      
          // 宏定义实体(数据表)名称
          #define ENTITY_STUDENT    @"Student"
  • 搭建 CoreData 环境

        // 声明目标对象上下文,CoreData 操作数据的环境
        @property (nonatomic, strong) NSManagedObjectContext *moc;
    
        // 托管对象模型文件路径
        NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"TestModel" ofType:@"momd"];
        NSURL *modelUrl = [NSURL fileURLWithPath:modelPath];
    
        // 创建托管对象模型,CoreData 数据模型文件
        NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelUrl];
    
        // 创建持久化存储协调器,处理数据的读写
        NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
    
        // SQLite 数据库文件路径,CoreData 使用的数据库文件后缀一般写 sqlite
        NSString *sqlPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject
                             stringByAppendingPathComponent:@"student.sqlite"];
        NSURL *sqlUrl = [NSURL fileURLWithPath:sqlPath];
    
        NSLog(@"sqlPath:%@", sqlPath);
    
        // 将 CoreData 文件映射到数据库,并判断操作状态
        NSError *error = nil;
    
        NSPersistentStore *store = [coordinator addPersistentStoreWithType:NSSQLiteStoreType 
                                                             configuration:nil URL:sqlUrl options:nil error:&error];
    
        if (!store) {
            NSLog(@"addError = %@", error);
        }
    
        // 创建操作数据的对象
        self.moc = [[NSManagedObjectContext alloc] init];
    
        // 关联持久化存储协调器
        self.moc.persistentStoreCoordinator = coordinator;
  • 插入数据

        // 获取插入到实体的指针
        Student *std = [NSEntityDescription insertNewObjectForEntityForName:ENTITY_STUDENT inManagedObjectContext:self.moc];
    
        // 赋值
        std.name = self.nameTF.text;
        std.age = self.ageTF.text.intValue;
    
        NSError *error = nil;
    
        // 同步到数据库并判断
        if ([self.moc save:&error]) {
    
            [self.myDataArray addObject:std];
            [self.myTableView reloadData];
        } else {
    
            NSLog(@"insert error = %@", error);
        }
  • 删除数据

        // 获取要删除的数据
        Student *std = self.myDataArray[self.selectedRow];
    
        // 从实体中删除
        [self.moc deleteObject:std];
    
        NSError *error = nil;
    
        // 同步到数据库并判断
        if ([self.moc save:&error]) {
    
            [self.myDataArray removeObjectAtIndex:self.selectedRow];
            [self.myTableView reloadData];
        } else {
    
            NSLog(@"delete error = %@", error);
        }
  • 修改数据

        // 获取要修改的数据
        Student *dent = self.myDataArray[self.selectedRow];
    
        // 赋值
        dent.name = self.nameTF.text;
        dent.age = self.ageTF.text.intValue;
    
        NSError *error = nil;
    
        // 同步到数据库并判断
        if ([self.moc save:&error]) {
    
            [self.myTableView reloadData];
        } else {
    
            NSLog(@"update error = %@", error);
        }
  • 查询数据

        // 查询请求
        NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:ENTITY_STUDENT];
    
        // 查询条件(正则表达式),name 以某些字符开头
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@",
                                 [NSString stringWithFormat:@"%@*", self.nameTF.text]];
    
        // 设置请求条件,如果不设查询条件会查询所有
        request.predicate = predicate;
    
        NSError *error = nil;
    
        // 执行查询
        self.myDataArray.array = [self.moc executeFetchRequest:request error:&error];
    
        if (error) {
    
            NSLog(@"fech = %@", error);
        } else {
    
            [self.myTableView reloadData];
        }
        // 查询所有 CoreData 数据
    
        // 查询请求
        NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:ENTITY_STUDENT];
    
        NSError *error = nil;
    
        // 查询
        NSArray *tmpArray = [self.moc executeFetchRequest:request error:&error];
    
        if (error) {
    
            NSLog(@"fech = %@", error);
        } else {
    
            // 将查询结果存储到数据源数组中
            [self.myDataArray setArray:tmpArray];
            [self.myTableView reloadData];
        }

3、MagicalRecord 的使用

  • CoreData 是 iOS 开发中经常使用的数据持久化的技术。但其操作过程稍微繁琐,即使你只是实现简单的存取,不涉及请求优化,也要进行许多配置工作,代码量在动辄几十行,对新手来说也需要较大时间成本。

  • MagicalRecord 是 OC 的一个库,协助方便 CoreData 的工作。其吸收了 Ruby on Rails 的 Active Record 模式,目标是:

    • 简化 Core Data 相关代码
    • 允许清晰,简单,单行获取
    • 当需要优化请求的时候,仍然允许修改 NSFetchRequest
  • 如果你在使用 MagicalRecord 方法的时候不想带 MR_ 前缀,直接用 findAll 代替 MR_findAll,就在引入头文件 CoreData+MagicalRecord.h 之前增加 #define MR_SHORTHAND 即可。

  • 配置

    • 创建 Model。创建一个 Model.xcdatamodeld ,添加一个 Person Entity,添加 age firstname lastname 三个属性。最后使用 Editor => Create NSManagedObject Subclass ORM 生成 Person 类。

      CoreData12

      CoreData13

    • 在使用的文件中引入头文件

          // 添加宏定义
          #define MR_SHORTHAND
      
          // 引入头文件
          #import "MagicalRecord.h"
  • 初始化

        - (void)viewDidLoad {
            [super viewDidLoad];
    
            // 初始化
            [MagicalRecord setupCoreDataStackWithStoreNamed:@"Model.sqlite"];
        }
    
        - (void)dealloc {
    
            // 清理
            [MagicalRecord cleanUp];
        }
  •     Person *person = [Person MR_createEntity];
    
        person.firstname = @"Frank";
        person.lastname = @"Zhang";
        person.age = 26;
    
        [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];
  •     Person *person = ...;       // 此处略,取出的数据模型
    
        [person MR_deleteEntity];
    
        [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];
  •     Person *person = ...;       // 此处略,取出的数据模型
    
        person.lastname = object;
    
        [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];
  •     // 查找数据库中的所有 Person。
        NSArray *persons = [Person MR_findAll];
    
        // 查找所有的 Person 并按照 first name 排序。
        NSArray *personsSorted = [Person MR_findAllSortedBy:@"firstname" ascending:YES];
    
        // 查找所有 age 属性为 25 的 Person 记录。
        NSArray *personsAgeEuqals25 = [Person MR_findByAttribute:@"age" withValue:[NSNumber numberWithInt:25]];
    
        // 查找数据库中的第一条记录
        Person *person = [Person MR_findFirst];
目录
相关文章
|
9月前
|
存储 关系型数据库 MySQL
MySQL——数据库备份上传到阿里云OSS存储
MySQL——数据库备份上传到阿里云OSS存储
348 0
|
1月前
|
SQL 存储 分布式数据库
分布式存储数据恢复—hbase和hive数据库数据恢复案例
分布式存储数据恢复环境: 16台某品牌R730xd服务器节点,每台服务器节点上有数台虚拟机。 虚拟机上部署Hbase和Hive数据库。 分布式存储故障: 数据库底层文件被误删除,数据库不能使用。要求恢复hbase和hive数据库。
77 12
|
2月前
|
存储 SQL NoSQL
【赵渝强老师】达梦数据库的逻辑存储结构
本文介绍了达梦数据库的存储结构,包括逻辑和物理存储两部分。逻辑存储结构由数据库(Database)、表空间(Tablespaces)、段(Segments)、簇(Cluster)和页(Page)组成。数据库是最大逻辑单元,包含所有表、索引等;表空间由数据文件组成,用于存储对象;段由簇构成,簇包含连续的数据页;页是最小存储单元。文中还提供了查询表空间、段和页大小的SQL语句,并附有视频讲解和示意图。
|
2月前
|
存储 SQL 安全
【赵渝强老师】达梦数据库的物理存储结构
本文介绍了达梦数据库的存储结构及各类物理文件的作用。达梦数据库通过逻辑和物理存储结构管理数据,包含配置文件(如dm.ini、sqllog.ini)、控制文件(dm.ctl)、数据文件(*.dbf)、重做日志文件(*.log)、归档日志文件、备份文件(*.bak)等。配置文件用于功能设置,控制文件记录数据库初始信息,数据文件存储实际数据,重做日志用于故障恢复,归档日志增强数据安全性,备份文件保障数据完整性,跟踪与事件日志辅助问题分析。这些文件共同确保数据库高效、稳定运行。
|
3月前
|
存储 关系型数据库 分布式数据库
PolarDB开源数据库进阶课3 共享存储在线扩容
本文继续探讨穷鬼玩PolarDB RAC一写多读集群系列,介绍如何在线扩容共享存储。实验环境依赖《在Docker容器中用loop设备模拟共享存储》搭建。主要步骤包括:1) 扩容虚拟磁盘;2) 刷新loop设备容量;3) 使用PFS工具进行文件系统扩容;4) 更新数据库实例以识别新空间。通过这些步骤,成功将共享存储从20GB扩容至30GB,并确保所有节点都能使用新的存储空间。
71 1
|
3月前
|
存储 人工智能 监控
时序数据库 TDengine 化工新签约:存储降本一半,查询提速十倍
化工行业在数字化转型过程中面临数据接入复杂、实时性要求高、系统集成难度大等诸多挑战。福州力川数码科技有限公司科技依托深厚的行业积累,精准聚焦行业痛点,并携手 TDengine 提供高效解决方案。
88 0
|
5月前
|
存储 druid 分布式数据库
列式存储数据库与超市的关系?
列式存储数据库是一种高效的数据管理方式,类似于超市将相似商品集中摆放。它将相同类型的数据(如年龄、价格)归类存储,便于快速查询和压缩,广泛应用于市场分析、财务报告和健康数据分析等领域。知名产品包括HBase、ClickHouse、Druid和Apache Cassandra等,适合处理大规模数据和实时分析任务。
80 4
|
6月前
|
存储 数据库
快速搭建南大通用GBase 8s数据库SSC共享存储集群
本文介绍如何GBase8s 数据库 在单机环境中快速部署SSC共享存储集群,涵盖准备工作、安装数据库、创建环境变量文件、准备数据存储目录、修改sqlhost、设置onconfig、搭建sds集群及集群检查等步骤,助你轻松完成集群功能验证。
|
5月前
|
存储 Oracle 关系型数据库
服务器数据恢复—华为S5300存储Oracle数据库恢复案例
服务器存储数据恢复环境: 华为S5300存储中有12块FC硬盘,其中11块硬盘作为数据盘组建了一组RAID5阵列,剩下的1块硬盘作为热备盘使用。基于RAID的LUN分配给linux操作系统使用,存放的数据主要是Oracle数据库。 服务器存储故障: RAID5阵列中1块硬盘出现故障离线,热备盘自动激活开始同步数据,在同步数据的过程中又一块硬盘离线,RAID5阵列瘫痪,上层LUN无法使用。
|
7月前
|
存储 关系型数据库 MySQL
PACS系统 中 dicom 文件在mysql 8.0 数据库中的 存储和读取(pydicom 库使用)
PACS系统 中 dicom 文件在mysql 8.0 数据库中的 存储和读取(pydicom 库使用)
187 2

热门文章

最新文章