1.手动创建CoreDataModel
2.添加实体和属性
3.创建持久化存储数据库
- (void)createData{
//1.创建模型对象
// 获取模型路径
NSURL *modelUrl = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"];
// 根据模型路径创建模型对象
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelUrl];
//2. 创建持久化存储助理:数据库
// 利用模型对象创建助理对象
NSPersistentStoreCoordinator *storeCoordinator = [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:model];
// 数据库的路径
NSString *dataName = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *sqlPath = [dataName stringByAppendingString:@"coreData.sqlite"];
NSLog(@"数据库 path = %@", sqlPath);
NSURL *sqlUrl = [NSURL fileURLWithPath:sqlPath];
NSError *sqlError = nil;
// 1.NSSQLiteStoreType (通过sqlite存储)
// 2.NSXMLStoreType (XML文件存储)
// 3.NSBinaryStoreType (二进制文件存储)
// 4.NSInMemoryStoreType (直接存储在内存中)
// 设置数据持久化存储协调器相关信息
// 这里的Type在创建成功之后更改为其它Type的话会报格式错误无法打开("The file couldn’t be opened because it isn’t in the correct format.")
[storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:sqlUrl options:nil error:&sqlError];
if (sqlError) {
NSLog(@"添加数据库失败:%@",sqlError);
} else {
NSLog(@"添加数据库成功");
}
// 创建管理上下文
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
context.persistentStoreCoordinator = storeCoordinator;
_context = context;
}
iOS10以后新增了一个NSPersistentContainer
类,这个类封装了CoreData
正常运行的所有对象,并提供了方便的方法和属性
NS_ASSUME_NONNULL_BEGIN
// An instance of NSPersistentContainer includes all objects needed to represent a functioning Core Data stack, and provides convenience methods and properties for common patterns.
API_AVAILABLE(macosx(10.12),ios(10.0),tvos(10.0),watchos(3.0))
@interface NSPersistentContainer : NSObject {
#if (!__OBJC2__)
@private
id _name;
NSManagedObjectContext *_viewContext;
id _storeCoordinator;
id _storeDescriptions;
#endif
}
+ (instancetype)persistentContainerWithName:(NSString *)name;
+ (instancetype)persistentContainerWithName:(NSString *)name managedObjectModel:(NSManagedObjectModel *)model;
+ (NSURL *)defaultDirectoryURL;
@property (copy, readonly) NSString *name;
@property (strong, readonly) NSManagedObjectContext *viewContext;
@property (strong, readonly) NSManagedObjectModel *managedObjectModel;
@property (strong, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (copy) NSArray *persistentStoreDescriptions;
// Creates a container using the model named `name` in the main bundle
- (instancetype)initWithName:(NSString *)name;
- (instancetype)initWithName:(NSString *)name managedObjectModel:(NSManagedObjectModel *)model NS_DESIGNATED_INITIALIZER;
// Load stores from the storeDescriptions property that have not already been successfully added to the container. The completion handler is called once for each store that succeeds or fails.
- (void)loadPersistentStoresWithCompletionHandler:(void (^)(NSPersistentStoreDescription *, NSError * _Nullable))block;
- (NSManagedObjectContext *)newBackgroundContext NS_RETURNS_RETAINED;
- (void)performBackgroundTask:(void (^)(NSManagedObjectContext *))block;
@end
NS_ASSUME_NONNULL_END
4、对数据进行简单的增删改查操作
// 新增数据
- (void)insertData{
// 1.根据Entity名称和NSManagedObjectContext获取一个新的继承于NSManagedObject的子类Student
Student * student = [NSEntityDescription
insertNewObjectForEntityForName:@"Student"
inManagedObjectContext:_context];
// 2.根据表Student中的键值,给NSManagedObject对象赋值
student.name = [NSString stringWithFormat:@"Mr-%d",arc4random()%100];
student.age = arc4random()%20;
student.height = arc4random()%180;
//查询所有数据的请求
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
NSArray *resArray = [_context executeFetchRequest:request error:nil];
_dataSource = [NSMutableArray arrayWithArray:resArray];
[self.tableView reloadData];
// 3.保存插入的数据
NSError *error = nil;
if ([_context save:&error]) {
NSLog(@"数据插入到数据库成功");
}else{
NSLog(@"数据插入到数据库失败, %@",error);
}
}
//删除数据
- (void)deleteData{
//创建删除请求
NSFetchRequest *deleRequest = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
//删除条件
NSPredicate *pre = [NSPredicate predicateWithFormat:@"age < %d", 10];
deleRequest.predicate = pre;
//返回需要删除的对象数组
NSArray *deleArray = [_context executeFetchRequest:deleRequest error:nil];
//从数据库中删除
for (Student *stu in deleArray) {
[_context deleteObject:stu];
}
//没有任何条件就是读取所有的数据
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
NSArray *resArray = [_context executeFetchRequest:request error:nil];
_dataSource = [NSMutableArray arrayWithArray:resArray];
[self.tableView reloadData];
NSError *error = nil;
//保存--记住保存
if ([_context save:&error]) {
NSLog(@"删除 age < 10 的数据, %@", error);
}else{
NSLog(@"删除数据失败, %@", error);
}
}
//修改更新数据
- (void)updateData{
//创建查询请求
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
NSPredicate *pre = [NSPredicate predicateWithFormat:@"age > %d", 10];
request.predicate = pre;
//发送请求
NSArray *resultArray = [_context executeFetchRequest:request error:nil];
//修改
for (Student *stu in resultArray) {
stu.name = @"iOS_Programmer";
stu.age = arc4random() % 8 + 1;
}
_dataSource = [NSMutableArray arrayWithArray: resultArray];
[self.tableView reloadData];
//保存
NSError *error = nil;
if ([_context save:&error]) {
NSLog(@"更新所有人的名字为“iOS_Programmer”");
}else{
NSLog(@"更新数据失败, %@", error);
}
}
//读取查询
- (void)readData{
/* 谓词的条件指令
1.比较运算符 > 、< 、== 、>= 、<= 、!=
例:@"number >= 99"
2.范围运算符:IN 、BETWEEN
例:@"number BETWEEN {1,5}"
@"address IN {'shanghai','nanjing'}"
3.字符串本身:SELF
例:@"SELF == 'APPLE'"
4.字符串相关:BEGINSWITH、ENDSWITH、CONTAINS
例: @"name CONTAIN[cd] 'ang'" //包含某个字符串
@"name BEGINSWITH[c] 'sh'" //以某个字符串开头
@"name ENDSWITH[d] 'ang'" //以某个字符串结束
5.通配符:LIKE
例:@"name LIKE[cd] '*er*'" // *代表通配符,Like也接受[cd].
@"name LIKE[cd] '???er*'"
*注*: 星号 "*" : 代表0个或多个字符
问号 "?" : 代表一个字符
6.正则表达式:MATCHES
例:NSString *regex = @"^A.+e$"; //以A开头,e结尾
@"name MATCHES %@",regex
注:[c]*不区分大小写 , [d]不区分发音符号即没有重音符号, [cd]既不区分大小写,也不区分发音符号。
7. 合计操作
ANY,SOME:指定下列表达式中的任意元素。比如,ANY children.age < 18。
ALL:指定下列表达式中的所有元素。比如,ALL children.age < 18。
NONE:指定下列表达式中没有的元素。比如,NONE children.age < 18。它在逻辑上等于NOT (ANY ...)。
IN:等于SQL的IN操作,左边的表达必须出现在右边指定的集合中。比如,name IN { 'Ben', 'Melissa', 'Nick' }。
提示:
1. 谓词中的匹配指令关键字通常使用大写字母
2. 谓词中可以使用格式字符串
3. 如果通过对象的key
path指定匹配条件,需要使用%K
*/
//创建查询请求
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
//查询条件
NSPredicate *pre = [NSPredicate predicateWithFormat:@"age = %d", 10];
request.predicate = pre;
// 从第几页开始显示
// 通过这个属性实现分页
//request.fetchOffset = 0;
// 每页显示多少条数据
//request.fetchLimit = 15;
//发送查询请求,并返回结果
NSArray *resArray = [_context executeFetchRequest:request error:nil];
_dataSource = [NSMutableArray arrayWithArray:resArray];
[self.tableView reloadData];
NSLog(@"查询所有年龄为10的学生");
}