项目开发--------CoreData 数据库
一.CoreData介绍
简介
Core Data是iOS5之后才出现的一个框架,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象。在此数据操作期间,我们不需要编写任何SQL语句,这个有点类似于著名的Hibernate持久化框架,不过功能肯定是没有Hibernate强大的。简单地用下图描述下它的作用:
左边是关系模型,即数据库,数据库里面有张person表,person表里面有id、name、age三个字段,而且有2条记录;
右边是对象模型,可以看到,有2个OC对象;
利用Core Data框架,我们就可以轻松地将数据库里面的2条记录转换成2个OC对象,也可以轻松地将2个OC对象保存到数据库中,变成2条表记录,而且不用写一条SQL语句。
模型文件
Person实体中有:name(姓名)、age(年龄)、card(身份证)三个属性
Card实体中有:no(号码)、person(人)两个属性
接下来看看创建模型文件的过程:
1.选择模板
2.添加实体
3.添加Person的2个基本属性
4.添加Card的1个基本属性
5.建立Card和Person的关联关系
右图中的表示Card中有个Person类型的person属性,目的就是建立Card跟Person之间的一对一关联关系(建议补上这一项),在Person中加上Inverse属性后,你会发现Card中Inverse属性也自动补上了
2.NSManagedObject的工作模式有点类似于NSDictionary对象,通过键-值对来存取所有的实体属性
1> setValue:forKey:存储属性值(属性名为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);
}
}