通过封装一个继承自NSObject单例实现数据库的管理
一、数据库模型和数据对象创建
1.创建Data Model
2.按下图序号1,2,3添加实体Entity
添加实体User,并为实体添加属性(price,name)和类型
3.创建NSManagedObject 子类,需要选择模型和实体
二、初始化对象并且打开数据库
1.使用CoreData管理数据,首先需要导入CoreData框架
2.封装一个单例数据库管理对象DatabaseManage,实现数据简单管理
以下为单例初始化方法,创建单例对象同时打开时数据库
+ (instancetype)shareInstance {
static DatabaseManager *instance = nil;
//token用来判断是否为第一次创建
static dispatch_once_t token;
dispatch_once(&token, ^{
instance = [[[self class] alloc] init];
//调用打开数据库方法
[instance openDataBase];
});
return instance;
}
3.封装打开数据库函数
1>加载Model路径的URL, 创建数据库NSManagedObjectModel对象
2>创建NSPersistentStoreCoordinate对象关联model,返回store
3>构建数据库存储路径,打开数据库( 如果没有则创建数据库)
4>关联store与数据库存储路径
5>创建NSManagedObjectContext 对象 ,用来操作数据
6>设置context 的持久数据库为store
- (void)openDataBase {
//(1)加载数据模型文件
NSURL *url = [[NSBundle mainBundle] URLForResource:@"DataModel" withExtension:@"momd"];
NSManagedObjectModel *dataModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:url];
//(2)打开数据库
NSPersistentStoreCoordinator *store = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:dataModel];
NSString *filePath = [NSHomeDirectory() stringByAppendingString:@"/Documents/coredata.sqlite"];
NSURL *dbURL = [NSURL fileURLWithPath:filePath];
[store addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil URL:dbURL
options:nil error:nil];
//(3)创建数据操作对象
self.context = [[NSManagedObjectContext alloc] init];
self.context.persistentStoreCoordinator = store;
}
4.增加数据
1>打开数据库
2>根据类名(字符串), 创建entity 对象
- (NSManagedObject *)createMO:(NSString *)entityName {
NSManagedObject *mo = [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:self.context];
return mo;
}
3>把创建的对象插入数据库
- (void)addManagedObject:(NSManagedObject *)mo {
[self.context insertObject:mo];
}
5.查询数据
1>打开数据库
2>构造请求NSFetchRequest
3>设置设置请求条件 NSPredicate
4>context 执行请求并返回 查询结果数组
示例代码:
- (NSArray *)query:(NSString *)entityName predicate:(NSPredicate *)predicate {
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName];
request.predicate = predicate;
NSArray *array = [self.context executeFetchRequest:request error:nil];
//返回的数组即为查询结果
return array;
}
6.删除数据
1>打开数据库
2>查询数据库
3>遍历查询结果
4>删除
- (void)delete:(NSString *)entityName predicate:(NSPredicate *)predicate{
NSArray *quaryResult = [self query:entityName predicate:predicate];
for (id obj in quaryResult){
[self.context deleteObject:obj];
}
[self.context save:nil];
}
7.由于修改数据实现封装效果,不灵活,不实现封装修改;
修改数据方法与删除数据方法相似
1>打开数据库
2> 构造请求NSFetchRequest对象,
3> 设置请求条NSPredicate对象,如:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age = 20"];
4>执行请求并返回查询结果 ,如:
NSArray *result = [context executeFetchRequest:request error:nil];
5>遍历查询结果, 在结果中修改数据,如:
for (User *user in users) {
user.name = @"Jack";
user.age = @20;
}
6>保存
[self.context save:nil];
三、多线程中查询数据
1.打开数据库
2.开启多线程,在多线程中必须创建新的NSManagedObjectContext文本对象,操作数据
- (IBAction)asyncQuery:(id)sender {
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
@autoreleasepool {
//1.新建一个context
NSManagedObjectContext *context1 = [[NSManagedObjectContext alloc] init];
context1.persistentStoreCoordinator = store;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"User"];
NSArray *array = [context1 executeFetchRequest:request error:nil];
for(User *usr in array) {
NSLog(@"id=%@,name=%@,age=%@", usr.userID,usr.userName,usr.userAge);
}
}
}];
}
3.在多线程中,数据保存到NSManagedObjectContext创建的对象context上会发送通知
4.在主线程中监听监听通知,
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSave:) name:NSManagedObjectContextDidSaveNotification object:nil];
5.执行接受到通知后的行为,即必须把多线程中context合并到主线程中context
- (void)contextDidSave:(NSNotification*)notification {
//判断通知对象是否为主线程context,若不是则合并到主线程
if (notification.object != context) {
[context mergeChangesFromContextDidSaveNotification:notification];
}