CoreData相关01 基础及运用:添加、查询、过滤、排序、分页

article/2025/8/19 20:24:54

CoreData

CoreData中几乎不用写数据库操作语句就能完成数据的本地化存储。

CoreData和iOS中的模型对象相联系在一起,只需要操作模型对象的增删改查就可以完成数据的增删改查,不用写SQL语句。

CoreData的存储方式

SQLite NSSQLiteStoreType
XML NSXMLStoreType
Binary NSBinaryStoreType
内存存储 NSInMemoryStoreType

CoreData的核心对象

NSManagedObjectContext 用途:负责应用与数据库之间的交互
NSPersistentStoreCoordinator 用途:添加持久化数据库,如SQLite
NSManagedObjectModel 用途:代表CoreData的模型文件
NSEntityDescription 用途:用于描述实体

CoreData的使用步骤

创建模型文件【相当于创建数据库】
添加实体【相当于创建表】
创建实体类【相当于创建模型】
生成上下文文件,关联模型文件生成数据库
保存对象到数据库
从数据库获取对象
更新数据
删除数据

创建上下文

在这里插入图片描述配置好后,创建文件:
在这里插入图片描述在这里插入图片描述创建完成。

接着配置一下工程项目配置:
在这里插入图片描述在这里插入图片描述然后在需要用到数据库的地方importCoreData框架,才可以使用CoreData相关的API。

这个时候如果编译上有遇到重复编译相关文件的错误提示的话,那就去这个地方将相关的提示文件删除即可。
在这里插入图片描述然后再需要调用的地方生成上下文,上下文是用来关联数据文件(CoreData__1.xcdatamodeld)的。

- (void)initCoreDataContext{//生成上下文,关联数据文件NSManagedObjectContext* context = [[NSManagedObjectContext alloc]init];//创建模型对象:mergedModelFromBundles:nil传入nil,会将bundle下所有的模型文件都关联起来NSManagedObjectModel* model = [NSManagedObjectModel mergedModelFromBundles:nil];//创建持久化调度器:NSPersistentStoreCoordinator* store = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];//获取存储数据库的名字//创建获取error的变量,用于接收错误NSError* error = nil;//创建数据库的存储路径:NSString* doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];NSString* sqlitePath = [doc stringByAppendingPathComponent:@"CoreData__1.sqlite"];NSURL* sqlURL = [NSURL fileURLWithPath:sqlitePath];NSLog(@"数据库位置:%@",sqlitePath);[store addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:sqlURL options:nil error:&error];context.persistentStoreCoordinator = store;self.context = context;
}

运行查看下文件路径有没有创建数据库文件:

2022-03-04 14:44:09.148267+0800 CoreData实践1[70691:2979529] 数据库位置:/Users/housnk/Library/Developer/CoreSimulator/Devices/1BD9D98C-0C2C-4F1A-8ADD-9158B1C4C938/data/Containers/Data/Application/6DBDFD9C-0D7E-449C-8B92-669DC0C0133F/Documents/CoreData__1.sqlite

用文件夹前往文件所在的位置:
在这里插入图片描述文件已生成没错。

添加数据

接着我们再创建一个方法用于添加数据:
PS:记得导入模型头文件。

#import "CoreData/Person+CoreDataProperties.h"
- (void)addInfo:(NSString*)name age:(int64_t)age{//用上下文来创建一个模型对象Person* person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.context];//给该模型对象赋值int numberID = arc4random()%10000;person.name = [NSString stringWithFormat:@"personSomeone%d",numberID];//旧版本的CoreData会将基本数据类型如Int、Float等包装成NSNumber对象,这里是新版本不用。int64_t personAge = arc4random()%100;person.age = personAge;//通过上下文保存://创建一个error用于接收错误,如果有错误的话。NSError* error = nil;[self.context save:&error];if (error) {NSLog(@"保存失败,错误信息:%@",error);}else{NSLog(@"保存成功");}
}

然后再运行一下,同样需要重新进入一下文件路径,因为每次编译后,其文件路径都有可能会改变。
运行结果:

2022-03-04 14:50:37.138301+0800 CoreData实践1[70833:2986457] 数据库位置:/Users/housnk/Library/Developer/CoreSimulator/Devices/1BD9D98C-0C2C-4F1A-8ADD-9158B1C4C938/data/Containers/Data/Application/6D76C9FC-93AA-4BC9-B443-C052171674E7/Documents/CoreData__1.sqlite
2022-03-04 14:50:37.185076+0800 CoreData实践1[70833:2986457] 保存成功

可以看到保存成功,有数据库查看软件的朋友可以进入到上面数据库存放的路径进行查阅。
没有数据库查看软件的朋友可以使用终端进行查看。这里使用终端进行查看软件。
打开终端,进入到数据库文件路径,如下:
在这里插入图片描述关于终端如何操作数据库可以点阅这篇文章:终端下简单查看SQLite数据库

查阅数据

- (void)readData{//创建请求对象(填入的是表名称)NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:@"Person"];//读取信息,几乎所有的增删改查都是使用context上下文进行操作//创建一个error用于接收错误,如果有错误的话。NSError* error = nil;//创建一个数组用于接收查询到的数据对象NSArray* resultArray = [self.context executeFetchRequest:request error:&error];if (error) {NSLog(@"查询失败,错误信息:%@",error);}else{NSLog(@"查询结果如下%@",resultArray);}
}

运行结果;

2022-03-04 15:36:29.121111+0800 CoreData实践1[71748:3018667] 查询结果如下("<Person: 0x60000010f020> (entity: Person; id: 0x913f42003aea29b9 <x-coredata://87F63B23-49E7-4631-B8A1-3305DFF756A4/Person/p1>; data: <fault>)"
)

由结果可得,其数组里面是Person对象,可以直接取出来用的。

过滤查询

接下来,我们用添加数据单元的方法,增加多几条数据,这个过程就不赘述了,主要是作为用于实践过滤查询的数据源,增加样本。
调用方式:

    //读取数据[self readAllData];//筛查[self filtrateData];

筛查部分执行代码:

- (void)filtrateData{//创建请求对象(填入的是表名称)NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:@"Person"];//创建过滤器NSPredicate* predicate = [NSPredicate predicateWithFormat:@"age<50"];request.predicate = predicate;//读取信息,几乎所有的增删改查都是使用context上下文进行操作//创建一个error用于接收错误,如果有错误的话。NSError* error = nil;//创建一个数组用于接收查询到的数据对象NSArray* resultArray = [self.context executeFetchRequest:request error:&error];if (error) {NSLog(@"查询失败,错误信息:%@",error);}else{NSLog(@"查询结果如下");for (Person* person in resultArray) {NSLog(@"personName:%@ age:%zd",person.name,person.age);}}
}

运行结果:

2022-03-04 15:52:48.250085+0800 CoreData实践1[72074:3032433] 查询结果如下
2022-03-04 15:52:48.250414+0800 CoreData实践1[72074:3032433] personName:personSomeone8011 age:92
2022-03-04 15:52:48.250558+0800 CoreData实践1[72074:3032433] personName:personSomeone5165 age:31
2022-03-04 15:52:48.250731+0800 CoreData实践1[72074:3032433] personName:personSomeone4661 age:1
2022-03-04 15:52:48.250833+0800 CoreData实践1[72074:3032433] personName:personSomeone5009 age:0
2022-03-04 15:52:48.250962+0800 CoreData实践1[72074:3032433] personName:personSomeone5947 age:85
2022-03-04 15:52:48.251089+0800 CoreData实践1[72074:3032433] personName:personSomeone7893 age:71
2022-03-04 15:52:48.251191+0800 CoreData实践1[72074:3032433] personName:personSomeone5098 age:40
2022-03-04 15:52:48.251342+0800 CoreData实践1[72074:3032433] personName:personSomeone4730 age:26
2022-03-04 15:52:48.251525+0800 CoreData实践1[72074:3032433] personName:personSomeone5643 age:61
2022-03-04 15:52:48.251730+0800 CoreData实践1[72074:3032433] personName:personSomeone2079 age:26
2022-03-04 15:52:48.252403+0800 CoreData实践1[72074:3032433] 查询结果如下
2022-03-04 15:52:48.253705+0800 CoreData实践1[72074:3032433] personName:personSomeone5165 age:31
2022-03-04 15:52:48.253820+0800 CoreData实践1[72074:3032433] personName:personSomeone4661 age:1
2022-03-04 15:52:48.253905+0800 CoreData实践1[72074:3032433] personName:personSomeone5009 age:0
2022-03-04 15:52:48.254002+0800 CoreData实践1[72074:3032433] personName:personSomeone5098 age:40
2022-03-04 15:52:48.254094+0800 CoreData实践1[72074:3032433] personName:personSomeone4730 age:26
2022-03-04 15:52:48.254196+0800 CoreData实践1[72074:3032433] personName:personSomeone2079 age:26

可以看到数据的确把age<50的给筛选出来了。

复杂的过滤查询

就是增加一些字符而已:
比如我要查询年纪大于18小于65的适龄劳动人员,那么就可以这么写:

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"age<65 AND age>18"];

运行结果:

2022-03-04 15:58:28.557047+0800 CoreData实践1[72165:3037445] 查询结果如下
2022-03-04 15:58:28.557156+0800 CoreData实践1[72165:3037445] personName:personSomeone5165 age:31
2022-03-04 15:58:28.640364+0800 CoreData实践1[72165:3037445] personName:personSomeone5098 age:40
2022-03-04 15:58:28.640592+0800 CoreData实践1[72165:3037445] personName:personSomeone4730 age:26
2022-03-04 15:58:28.640689+0800 CoreData实践1[72165:3037445] personName:personSomeone5643 age:61
2022-03-04 15:58:28.640776+0800 CoreData实践1[72165:3037445] personName:personSomeone2079 age:26

对结果排序

- (void)filtrateAndSortData{//创建请求对象(填入的是表名称)NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:@"Person"];//创建过滤器NSPredicate* predicate = [NSPredicate predicateWithFormat:@"age<65 AND age>18"];request.predicate = predicate;//读取信息,几乎所有的增删改查都是使用context上下文进行操作//以年纪进行排序NSSortDescriptor* sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES];request.sortDescriptors = @[sort];//创建一个error用于接收错误,如果有错误的话。NSError* error = nil;//创建一个数组用于接收查询到的数据对象NSArray* resultArray = [self.context executeFetchRequest:request error:&error];if (error) {NSLog(@"查询失败,错误信息:%@",error);}else{NSLog(@"查询结果如下");for (Person* person in resultArray) {NSLog(@"personName:%@ age:%zd",person.name,person.age);}}
}

运行结果:

2022-03-04 16:09:23.233057+0800 CoreData实践1[72352:3044306] 查询结果如下
2022-03-04 16:09:23.233216+0800 CoreData实践1[72352:3044306] personName:personSomeone4730 age:26
2022-03-04 16:09:23.233541+0800 CoreData实践1[72352:3044306] personName:personSomeone2079 age:26
2022-03-04 16:09:23.233638+0800 CoreData实践1[72352:3044306] personName:personSomeone5165 age:31
2022-03-04 16:09:23.233740+0800 CoreData实践1[72352:3044306] personName:personSomeone5098 age:40
2022-03-04 16:09:23.233823+0800 CoreData实践1[72352:3044306] personName:personSomeone5643 age:61

分页查询

分页数据,emmm,数据量又不够了,所以我们向数据中多添加一些数据,这个过程同样不赘述了。

- (void)pagingQueryData{//创建请求对象(填入的是表名称)NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:@"Person"];//每页显示8条数据request.fetchLimit = 8;//跳过数据量request.fetchOffset = 0;//创建一个error用于接收错误,如果有错误的话。NSError* error = nil;//创建一个数组用于接收查询到的数据对象NSArray* resultArray = [self.context executeFetchRequest:request error:&error];if (error) {NSLog(@"查询失败,错误信息:%@",error);}else{NSLog(@"查询结果如下");for (Person* person in resultArray) {NSLog(@"personName:%@ age:%lld",person.name,person.age);}}
}

运行代码:

2022-03-04 16:27:23.550483+0800 CoreData实践1[72820:3059276] 查询结果如下
2022-03-04 16:27:23.550997+0800 CoreData实践1[72820:3059276] personName:personSomeone8011 age:92
2022-03-04 16:27:23.551868+0800 CoreData实践1[72820:3059276] personName:personSomeone5165 age:31
2022-03-04 16:27:23.552171+0800 CoreData实践1[72820:3059276] personName:personSomeone4661 age:1
2022-03-04 16:27:23.552477+0800 CoreData实践1[72820:3059276] personName:personSomeone5009 age:0
2022-03-04 16:27:23.552932+0800 CoreData实践1[72820:3059276] personName:personSomeone5947 age:85
2022-03-04 16:27:23.553361+0800 CoreData实践1[72820:3059276] personName:personSomeone7893 age:71
2022-03-04 16:27:23.553687+0800 CoreData实践1[72820:3059276] personName:personSomeone5098 age:40
2022-03-04 16:27:23.554317+0800 CoreData实践1[72820:3059276] personName:personSomeone4730 age:26

从运行结果中可以看到获取的数据量已经被限定在8个条数了,如果要看第二页数据,则:

request.fetchOffset = 8;

如果要看第三页数据,则:

request.fetchOffset = 16;

如此类推。


http://chatgpt.dhexx.cn/article/EUisEvjl.shtml

相关文章

JVM原理分析

JVM原理分析 为什么Java是一种跨平台语言 1、不同系统的JDK下载 JDK里面有&#xff1a;Jre和Jvm&#xff0c;其中就有JVM指令集的不同 JVM主要结构&#xff1a; 栈、堆、方法区、程序计数器、本地方法栈 mian方法的执行 通过类装载子系统进入JVM 其中栈中存放线程 来一个…

JVM实现原理

JVM原理 1、概念简介2、为什么要学习JVM虚拟机&#xff1f;3、JVM怎么学&#xff1f;3.1 内存管理1、jvm运行时数据区 1、概念简介 JVM&#xff1a;JAVA虚拟机JRE&#xff1a;Java运行环境 JREJVM虚拟机Java核心类库支持文件JDK&#xff1a;Java开发工具包 JDKJREJava工具Java…

【JVM调优】JVM原理与性能调优

一、参考资料 今日头条https://www.toutiao.com/i7007696978586976805

JVM原理和调优的理解和学习

JVM原理和调优的理解和学习 一、详解JVM内存模型二、JVM中一次完整的GC流程是怎样的三、GC垃圾回收的算法有哪些四、简单说说你了解的类加载器五、双亲委派机制是什么&#xff0c;有什么好处&#xff0c;怎么打破六、说说你JVM调优的几种主要的JVM参数七、JVM调优八、类加载的机…

JVM原理-jvm内存模型

一、jvm内存模型 结构图 JVM包含两个子系统和两个组件 Class loader(类装载子系统) 根据给定的全限定名类名(如&#xff1a;java.lang.Object)来装载class文件到 Runtime data area运行时数据区中的method area方法区中Execution engine(执行引擎) 执行classes中的指令Runt…

JVM原理-垃圾回收机制及算法

JVM原理-jvm内存模型 jvm内存模型 一、垃圾回收机制算法 1、 判断对象是否回收算法 垃圾收集器在做垃圾回收的时候&#xff0c;首先需要判定的就是哪些内存是需要被回收的&#xff0c;哪些对象是存活的&#xff0c;是不可以被回收的&#xff1b;哪些对象已经死掉了&#xf…

jvm面试原理

1、什么是JVM JVM是Java Virtual Machine&#xff08;Java虚拟机&#xff09;的缩写&#xff0c;JVM是一种用于计算设备的规范&#xff0c;它是一个虚构出来的计算机&#xff0c;是通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机包括一套字节码指令集、一组…

JVM原理和JVM内存的整理

JVM原理及JVM内存 JVM原理及JVM内存概念这么说1.JVM的基本过程2.JVM的中的“解释”原理&#xff0c;三个重要机制3.JVM的体系结构4.运行时数据区JVM垃圾回收 JVM原理及JVM内存 之前看了许多JVM原理的文章、写作的大牛们都讲的很透彻&#xff0c;但是私下觉得&#xff1a;写得详…

JVM原理和调优(读这一篇就够了)

前言 抛2个问题&#xff1a; 1、export JAVA_OPTS"-Xms256m -Xmx512m -Xss256m -XX:PermSize512m -XX:MaxPermSize1024m -Djava.rmi.server.hostname136.64.45.24 -Dcom.sun.management.jmxremote.port9315 -Dcom.sun.management.jmxremote.sslfalse -Dcom.sun.manageme…

JVM工作原理

JVM的生命周期 &#xff08;1&#xff09;两个概念&#xff1a;JVM实例和JVM执行引擎实例 JVM实例对应了一个独立运行的java程序&#xff0c;它是进程级别的 JVM执行引擎实例则对应了属于用户运行程序的线程&#xff0c;它是线程级别的 &#xff08;2&#xff09;VM实例的诞生…

JVM原理与实战

JVM原理 类加载流程和内存分配栈帧操作一、JVM垃圾回收算法主动加载的几种方式?符号引用和直接引用1.1 什么是垃圾(Garbage Collection)回收?1.2 引用计数法(Reference Conting)1.3 标记清除法 *(Mark - Sweep)1.4 复制算法 *(Copying)1.4.1 复制算法在JVM中的应用1.…

jvm原理与性能调优

文章目录 一、JVM内存结构 1.运行时数据区 2.直接内存 二、JVM中的对象 1.对象的创建 2.对象的内存布局 3.对象的访问定位 三、垃圾回收算法和垃圾回收器 1. 如何判断对象是已死 2.分代回收理论 3.垃圾回收算法 4.垃圾收集器 四、JVM执行子系统 1.Class文件结构 2.类加载机制 3…

什么是JVM?深入解析JVM原理!

一、JVM是什么? JVM是Java Virtual Machine(Java虚拟机)的缩写,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。由一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域等组成。JVM屏蔽了与操作系统平台相关的信息,使得Java程序只需要生成在J…

全面阐述JVM原理

一 JVM入门 1. 什么是JVM JVM是Java Virtual Machine&#xff08;Java虚拟机&#xff09;的缩写&#xff0c;JVM是一种用于计算设备的规范&#xff0c;它是一个虚构出来的计算机&#xff0c;是通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机包括一套字节码…

JVM原理

JVM原理 一.jvm简介 JVM是Java Virual Machine&#xff08;Java虚拟机&#xff09;的缩写&#xff0c;JVM是一种用于计算设备的规范&#xff0c;他是一个虚构出来的计算机&#xff0c;是通过在实际的计算机上仿真模拟计算机功能来实现的。Java虚拟机包括一套字节码指令集、一组…

JVM原理详解

主题内容&#xff1a; 1.JVM 内存区域概览 2.堆区的空间分配是怎么样&#xff1f;堆溢出的演示 3.创建一个新对象内存是怎么分配的&#xff1f; 4.方法区 到 Metaspace 元空间 5.栈帧是什么&#xff1f;栈帧里有什么&#xff1f;怎么理解&#xff1f; 6.本地方法栈 7.程序…

JVM的运行原理

目录 1.概念 2.JVM运行机制 3.JVM执行流程 4.JVM运行时数据区 什么是线程私有? OOM&#xff08;内存溢出&#xff09; 4.1 堆&#xff1a;也叫运行时数据区&#xff0c;线程共享 4.2 方法区&#xff1a;线程共享 4.3 Java虚拟机栈&#xff1a;线程私有&#xff0c;描…

JVM的原理

JVM原理(一) 1、JVM总体结构图 2、JVM堆结构图以及分代 复制算法&#xff1a; 1、新生成的对象存放在Eden区和from区 2、当Eden区内存不够&#xff0c;虚拟机将发起一次MinorGC 3、GC进行时&#xff0c;Eden区中所有存活的对象都会被复制到to区 4、年龄阀值达到15的会被放到老年…

JAVA虚拟机JVM工作原理

提起JAVA&#xff0c;都知道它有个虚拟机&#xff0c;因此可以跨平台&#xff0c;一次编写&#xff0c;到处运行。但具体原理是咋样的&#xff1f;身为JAVA小白&#xff0c;岂可不知&#xff01; 一、原理 二、结构 1、类加载器 2、执行引擎 3、运行时数据区域一、原理 JVM实现…