對于這兩個持久化框架一直存在爭議,公司里的項目一直都是會用coredata,一直對coredata印象還不錯,再加上MagicalRecord對coredata的封裝,使用起來就更簡單了。FMDB用的很少,只知道對數據庫操作都是手寫sql語句執行,聽起來性能應該更好,所以特意來對比一下。
測試過程很簡單,就對比了個操作
1:在一個空表(6個字段)插入十萬條數據
2:更新十萬數據的其中一個字段
Coredata
用coredata怎么能少得了MagicalRecord框架
- 集成MagicalRecord
使用cocoapods集成 -
創建模型文件和實體
這個表就6個字段
QQ20160917-9@2x.png -
生成實體類
QQ20160917-10@2x.png - 初始化數據庫
在AppDelegate.m添加如下代碼
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[MagicalRecord setDefaultModelNamed:@"Model.momd"];
[MagicalRecord setupCoreDataStackWithStoreNamed:@"coredataDemo.db"];
return YES;
}```
- 插入數據
點擊屏幕的時候執行
NSLog(@"開始存儲");
[MagicalRecord saveWithBlock:^(NSManagedObjectContext * _Nonnull localContext) {
for (int i=0; i<100000; i++) {
User *user=[User MR_createEntityInContext:localContext];
user.id=1000+i;
user.name=[NSString stringWithFormat:@"ygc%d",i];
user.mobilephone=@"13888886666";
user.address=@"北京天安門廣場101北京天安門廣場101北京天安門廣場101北京天安門廣場101北京天安門廣場101";
user.age=arc4random_uniform(10)+20;
user.gender=i%2;
}
} completion:^(BOOL contextDidSave, NSError * _Nullable error) {
NSLog(@"結束存儲");
}];
查看本地數據庫,驗證數據是否插入成功

結果如下,耗時3.6秒

- 更新數據
將address字段更新,全表1000數據
NSLog(@"開始更新");
[MagicalRecord saveWithBlock:^(NSManagedObjectContext * _Nonnull localContext) {
NSArray *users=[User MR_findAllInContext:localContext];
if(users)
{
for (User *user in users) {
user.address=@"上海東方明珠101上海東方明珠101上海東方明珠101上海東方明珠101上海東方明珠101上海東方明珠101";
}
}
} completion:^(BOOL contextDidSave, NSError * _Nullable error) {
NSLog(@"結束更新");
}];
結果如下,耗時4.8秒,由于coredata是面對對象的數據庫,所以必須先把數據查出來,然修改對象的值,再提交保存。所以更新的過程多了一個查詢的耗時

###FMDB
- 集成FMDB
使用cocoapods集成
pod 'MagicalRecord', '~> 2.3.2'
- 初始化數據庫并建表
-(void)setUpDatabase
{
if(!_db)
{
NSString *path=[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"fmdb.db"];
FMDatabase *db=[FMDatabase databaseWithPath:path];
if([db open])
{
_db=db;
[self createTables];
}
}
}
-(void)createTables
{
NSString *query=@"CREATE TABLE USER ( id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age INTEGER, gender INTEGER, address VARCHAR, mobilphone VARCHAR )";
if([self.db executeUpdate:query])
{
NSLog(@"建表成功");
}
else
{
NSLog(@"建表失敗");
}
}
- 插入操作
和上面一樣,插入十萬條數據,內容一樣
```-(void)insert
{
NSLog(@"開始插入");
for (int i=0; i<100000; i++) {
NSString *name=[NSString stringWithFormat:@"ygc%d",i];
NSString *mobilephone=@"13888886666";
NSString *address=@"北京天安門廣場101北京天安門廣場101北京天安門廣場101北京天安門廣場101北京天安門廣場101";
NSUInteger age=arc4random_uniform(10)+20;
NSUInteger gender=i%2;
BOOL succes= [[DBTool sharedInstance].db executeUpdateWithFormat:@"insert into USER(name,age,gender,address,mobilphone) values (%@,%d,%d,%@,%@)",name,age,gender,address,mobilephone];
}
NSLog(@"結束插入");
}
執行結果如下,耗時68秒
- 更新操作
代碼如下
-(void)update
{
//開始更新
NSLog(@"開始更新");
[[DBTool sharedInstance].db executeUpdateWithFormat:@"update USER set address=%@",@"上海東方明珠101上海東方明珠101上海東方明珠101上海東方明珠101上海東方明珠101上海東方明珠101"];
NSLog(@"結束更新");
}
執行結果如下,耗時0.3秒,由于直接對表字段操作,所以速度很快
結果統計
對比結果下來,從性能上講,也沒有絕對的好與差,得看實際項目使用情況,并且還有優化的空間。不過從代碼維護成本和學習成本來講的話,還是coredata簡單些(入門級別),語法上也很好接受。我傾向coredata還有一個很好的功能是coredata可以監聽一個表的數據變化(NSFeatchResultController),是插入還是刪除,還是修改,配合tableView很好做一些動畫。不知道FMDB有沒有這樣的功能,還是要自己手動實現?