CoreData數(shù)據(jù)庫的基本使用

一、CoreData介紹

CoreData是蘋果公司封裝的數(shù)據(jù)持久化框架。說白了就是對SQLite進行的封裝 CoreData在iOS 3.0中開始開放, 它允許用戶按照實體-屬性-值模型組織數(shù)據(jù),數(shù)據(jù)最終的存儲形式可以是:二進制、XML、SQLite數(shù)據(jù)庫、內存里、活自定義數(shù)據(jù)類型
如果要了解SQLite的的使用可以參閱博客 :http://www.itdecent.cn/p/0b9b78e704a4
CoreData的優(yōu)勢
1 它是蘋果公司原生態(tài)的產品。
2 它可以節(jié)省代碼量 大概是30%-70%。
3 它支持可視化建模。
4 CoreData支持數(shù)據(jù)庫版本升級

CoreData的構成
(1)NSManagedObjectContext 被管理者對象上下文 相當于一個臨時數(shù)據(jù)庫 我們存儲或者查詢都是通過這個對象來的
(2)NSManagedObjectModel 被管理對象模型,可以簡單的理解為可視化建模文件 我們在可視化建模中是Entity自動生成model 方便讓文件存儲助理來進行管理
(3)NSPersistentStoreCoordinator 文件存儲助理,相當于數(shù)據(jù)庫的鏈接器,它是CpreData的核心 他負責鏈接所有的模塊 包括真實的存儲文件
(4)NSManagedObject 被管理的數(shù)據(jù)記錄, 相當于數(shù)據(jù)庫中的表格記錄
(5)NSFetchRequest 獲取數(shù)據(jù)的請求,相當于SQL語句
(6)NSEntityDescription 實體結構,相當于表結構
(7)后綴為.xcdatamodeld的包 里面是.xcodemodel文件 用數(shù)據(jù)模型編輯器編譯。編譯后為.momd或.mom文件

二、使用簡介

我們創(chuàng)建一個工程,在創(chuàng)建的時候選擇使用 Core Data



在AppDelegate里面會相比不使用CoreData多出來幾個屬性和方法 在以下代碼中都加了非常詳細的代碼

#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
//被管理對象上下文,相當于一個臨時數(shù)據(jù)庫 我們存儲或者查詢都是通過這個對象來的
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
//被管理對象模型,可以簡單的理解為可視化建模文件 我們在可視化建模中是Entity自動生成model 方便讓文件存儲助理來進行管理
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
//文件存儲助理,他是CpreData的核心 他負責鏈接所有的模塊 包括真實的存儲文件
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
//將我們在內存中的操作進行持久化
- (void)saveContext;
//獲取真實文件的路徑
- (NSURL *)applicationDocumentsDirectory;
@end

緊接著我們在點擊后綴為.xcdatamodeld



接下來 并根據(jù)提示做如下操作



點擊create

那么在我們的工程中就出現(xiàn)了類似下圖的幾個文件 我們在使用的時候直接引入頭文件就可以Student.h或者Person.h就可以了


三、增、刪、改、查的實現(xiàn)

接下來我們來實現(xiàn)什么功能呢?請看下圖



我們創(chuàng)建一個類CoreDataTableViewController 繼承自UITableViewController

.h
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
@interface CoreDataTableViewController : UITableViewController
//創(chuàng)建一個上下文對象 用于處理所有與存儲相關的請求
@property(nonatomic,strong)NSManagedObjectContext *myContext;
//創(chuàng)建一個數(shù)組用于存儲數(shù)組的數(shù)據(jù)源
@property(nonatomic,strong)NSMutableArray *allData;
@end

.m
- (void)viewDidLoad {
    [super viewDidLoad];
    //進行數(shù)據(jù)初始化
    AppDelegate *delegate= [UIApplication sharedApplication].delegate;
    self.myContext = delegate.managedObjectContext;
    self.allData = [NSMutableArray array];
    //通過coreData讀取本地所有的數(shù)據(jù)
    [self getAllDataFromCoreData];
}

1、增加

- (IBAction)addData:(id)sender {
    //創(chuàng)建student對象
    NSEntityDescription *description = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:_myContext];
  
    Student *student = [[Student alloc]initWithEntity:description insertIntoManagedObjectContext:_myContext];
    
    //給屬性賦值
    student.name = @"張三";
    student.age = arc4random()%73+1;

    //修改數(shù)據(jù)源
    [_allData addObject:student];
    
    //修改界面
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.allData.count -1 inSection:0];
    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
    //將數(shù)據(jù)保存到文件中進行持久化 
/*
//    NSError *error = nil;
//    [self.myContext save:&error];
//    
//    if (nil != error) {
//        NSLog(@"數(shù)據(jù)持久化存在問題");
//    }
*/  
//等同于以上實例持久化方式
    [(AppDelegate *)[UIApplication sharedApplication].delegate saveContext];
}

2、刪除

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        
        //獲取當前cell代表的數(shù)據(jù)
        Student *stu = _allData[indexPath.row];
        
        //修改數(shù)據(jù)源
        [self.allData removeObject:stu];
        
        //更新UI
        [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
        
        //將臨時數(shù)據(jù)庫里進行刪除并進行本地持久化
        [self.myContext deleteObject:stu];
        
        [self.myContext save:nil];
    }
}

3、修改

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:_myContext];
    [fetchRequest setEntity:entity];

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"age"
                                                                   ascending:YES];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]];
    NSError *error = nil;
    NSArray *fetchedObjects = [_myContext executeFetchRequest:fetchRequest error:&error];
    if (fetchedObjects != nil) {
        //修改對應的數(shù)據(jù)
        Student *stu = fetchedObjects[indexPath.row];
        stu.name = @"尼古拉斯&趙四";
        //更新數(shù)據(jù)源
        [self.allData removeAllObjects];
        [self.allData addObjectsFromArray:fetchedObjects];   
        //更新界面
        [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft]; 
        //將修改本地持久化
        [self.myContext save:nil];
    }
}

4、查詢

-(void)getAllDataFromCoreData{
    
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:_myContext];
    [fetchRequest setEntity:entity];
    // Specify criteria for filtering which objects to fetch
    
    //排序條件
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"age" ascending:YES];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]];
    
    NSError *error = nil;
    NSArray *fetchedObjects = [_myContext executeFetchRequest:fetchRequest error:&error];
    if (fetchedObjects == nil) {
        NSLog(@"兩手空空,你讓倫家盆滿缽滿");
    }
    //將查詢到的數(shù)據(jù)添加到數(shù)據(jù)源
    [self.allData addObjectsFromArray:fetchedObjects];
    //重新加載tableView
    [self.tableView reloadData];
}

四、關系建立

實際我們在項目中建立起來的模型對象并不是孤立存在的例如:Company(公司) 和 Employee(雇員)之間是存在歸屬關系的 我們就依此為例
首先我們創(chuàng)建兩個模型對象 Company 和 Employee



那么我們如何建立起公司和職員之間的鏈接呢?往下看



代碼實例如下:
#import "ViewController.h"
#import "Company.h"
#import "Employee.h"
#import "AppDelegate.h"
@interface ViewController ()
@property(nonatomic,strong)NSManagedObjectContext *myContext;
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.myContext = ((AppDelegate *)[UIApplication sharedApplication].delegate).managedObjectContext;
    Company *company = [[Company alloc]initWithEntity:[NSEntityDescription entityForName:@"Company" inManagedObjectContext:self.myContext] insertIntoManagedObjectContext:self.myContext];
    company.name = @"網(wǎng)易新聞";
    company.address = @"中關村東路1號院清華科技園D座";
    Employee *emp1 = [[Employee alloc]initWithEntity:[NSEntityDescription entityForName:@"Employee" inManagedObjectContext:self.myContext] insertIntoManagedObjectContext:self.myContext];
    emp1.name = @"趙二";
    emp1.age =21;
    Employee *emp2 = [[Employee alloc]initWithEntity:[NSEntityDescription entityForName:@"Employee" inManagedObjectContext:self.myContext] insertIntoManagedObjectContext:self.myContext];
    emp2.name = @"見哥";
    emp2.age = 22;
    [company addBelongObject:emp1];
    [company addBelongObject:emp2];
    [self.myContext save:nil];
    #pragma mark ------模擬讀取查詢
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Company" inManagedObjectContext:self.myContext];
    [fetchRequest setEntity:entity];
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]];
    NSError *error = nil;
    NSArray *fetchedObjects = [self.myContext executeFetchRequest:fetchRequest error:&error];
    if (fetchedObjects == nil) {
        NSLog(@"兩手空空,大變活人");
    }
    Company *com =fetchedObjects[0];
    //這里我們知道只是存了一個
    NSLog(@"%@--%@",com.name,com.address);
    for (Employee *em in com.belong) {
        NSLog(@"name:%@,age = %d",em.name,em.age);
    }
}

五、數(shù)據(jù)庫版本升級

實際上開發(fā)過程中數(shù)據(jù)庫的版本升級也是很常見的 怎么實現(xiàn)呢?在這里直接上圖 簡單明了



這時候我們多了新的.xcdatamodeld文件 綠色對勾表示當前選擇數(shù)據(jù)庫NSManagedObjectModel




以上就是關于CoreData的基本用法。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容