ios CoreData和FMDB最新使用问题总结
来源:互联网 发布:电视盒子推荐 知乎 编辑:程序博客网 时间:2024/06/09 13:55
1.xcode8 无法创建NSManagedObjectModel subClass和 创建NSManagedObjectModel subClass为swift版本 问题解决见链接 点击打开链接
2.FMDB和CoreData性能问题比较
1)经过楼主真机测试,大量数据插入(超过1万条) FMDB经过伪批处理之后的性能和CoreData性能旗鼓相当,一万条数据 500 ms左右。
解释一下FMDB的伪批处理,因为FMDB默认每条插入操作都当做一次事务处理,所以单纯直接循环10000次插入操作,时间消耗非常之大,10000条数据约需三分钟,如果采用统一开启事务处理方式,FMDB自动取消每次插入的事务,处理速度大大加快,就是上述 10000条数据 500 ms左右。
伪批处理(统一事务处理)代码如下:
//增加数据- (void)addFMDB { [self.db beginTransaction]; BOOL isRollBack = NO; @try { //往表中循环插入100条数据 for (int i = 0; i < 50000 ; i++) { //名称设置为J_mailbox NSString *name = [NSString stringWithFormat:@"J_mailbox-%d",i]; //随机生成20岁~25岁之间的记录 NSInteger age = arc4random_uniform(5) + 20; //sql插入语句的拼接 NSString *resultStr = [NSString stringWithFormat:@"INSERT INTO t_test (NAME,AGE) VALUES('%@',%zd) ",name,age]; //执行sql插入语句(调用FMDB对象方法) BOOL success = [self.db executeUpdate:resultStr]; //判断是否添加成功// if (success) {// NSLog(@"添加数据成功!");// }else{// NSLog(@"添加数据失败!");// } } } @catch (NSException *exception) { isRollBack = YES; [self.db rollback]; } @finally { if (!isRollBack) { [self.db commit]; NSLog(@"最终成功"); } }}2) 对于查询操作,而且速度差不多,但对于批量删除操作,批量更新操作,由于CoreData需要先查询找到相应的实体对象然后再执行更新操作,效率低了很多。
3.完整FMDB和CoreData对比demo示例代码如下
#import "ViewController.h"#import <sqlite3.h>#import "FMDB.h"#import <CoreData/CoreData.h>@interface ViewController ()@property (strong,nonatomic) FMDatabase *db;@property (strong,nonatomic) NSManagedObjectContext *coreDataContext;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; [self initUI]; [self connectionDB]; [self initCoreData];}-(void)operetionClick:(UIButton *)btn{ CFAbsoluteTime startTime =CFAbsoluteTimeGetCurrent(); if (btn.tag < 4) { //fmdb switch (btn.tag) { case 0: { [self addFMDB]; } break; case 1: { [self deleteFMDB]; } break; case 2: { [self changeFMDB]; } break; case 3: { [self queryFMDB]; } break; default: break; } } else { //core Data switch (btn.tag) { case 4: { [self addCoreData]; } break; case 5: { [self deleteCoreData]; } break; case 6: { } break; case 7: { [self queryCoreData]; } break; default: break; } } CFAbsoluteTime linkTime = (CFAbsoluteTimeGetCurrent() - startTime); NSLog(@"Linked in %f ms", linkTime *1000.0);}- (void)initCoreData{ // 从应用程序包中加载模型文件 NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil]; // 传入模型对象,初始化NSPersistentStoreCoordinator NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model]; // 构建SQLite数据库文件的路径 NSString *docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSURL *url = [NSURL fileURLWithPath:[docs stringByAppendingPathComponent:@"person.data"]]; NSLog(@"%@",url); // 添加持久化存储库,这里使用SQLite作为存储库 NSError *error = nil; NSPersistentStore *store = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error]; if (store == nil) { // 直接抛异常 [NSException raise:@"添加数据库错误" format:@"%@", [error localizedDescription]]; } // 初始化上下文,设置persistentStoreCoordinator属性 NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init]; context.persistentStoreCoordinator = psc; self.coreDataContext = context;}- (void)addCoreData{ for (int i = 0; i < 10000; i++) { NSManagedObject *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.coreDataContext]; // 设置Person的简单属性 [person setValue:[NSString stringWithFormat:@"zss%d",i] forKey:@"name"]; [person setValue:[NSNumber numberWithInt:27] forKey:@"age"]; } // 利用上下文对象,将数据同步到持久化存储库 NSError *error = nil; BOOL success = [self.coreDataContext save:&error]; if (!success) { [NSException raise:@"访问数据库错误" format:@"%@", [error localizedDescription]]; } else { NSLog(@"全部添加成功"); }}- (void)queryCoreData{ // 初始化一个查询请求 NSFetchRequest *request = [[NSFetchRequest alloc] init]; // 设置要查询的实体 request.entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:self.coreDataContext]; // 设置排序(按照age降序)// NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:NO];// request.sortDescriptors = [NSArray arrayWithObject:sort]; // 设置条件过滤(搜索name中包含字符串"Itcast-1"的记录,注意:设置条件过滤时,数据库SQL语句中的%要用*来代替,所以%Itcast-1%应该写成*Itcast-1*)// NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@", @"*Itcast-1*"];// request.predicate = predicate; // 执行请求 NSError *error = nil; NSArray *objs = [self.coreDataContext executeFetchRequest:request error:&error]; if (error) { [NSException raise:@"查询错误" format:@"%@", [error localizedDescription]]; } // 遍历数据 for (NSManagedObject *obj in objs) { NSLog(@"name=%@", [obj valueForKey:@"name"]); }}- (void)deleteCoreData{ // 初始化一个查询请求 NSFetchRequest *request = [[NSFetchRequest alloc] init]; // 设置要查询的实体 request.entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:self.coreDataContext]; NSError *error = nil; NSArray *objs = [self.coreDataContext executeFetchRequest:request error:&error]; if (error) { [NSException raise:@"查询错误" format:@"%@", [error localizedDescription]]; } // 遍历数据 for (NSManagedObject *obj in objs) { // 传入需要删除的实体对象 [self.coreDataContext deleteObject:obj]; } // 将结果同步到数据库 error = nil; [self.coreDataContext save:&error]; if (error) { [NSException raise:@"删除错误" format:@"%@", [error localizedDescription]]; } else { NSLog(@"全部删除成功"); }}//连接数据库- (void)connectionDB{ //创建数据库路径 NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"data.sqlite"]; NSLog(@"%@",path); FMDatabase *db = [FMDatabase databaseWithPath:path]; self.db = db; BOOL success = [db open]; if (success) { //打开成功 NSLog(@"数据库创建成功!"); //创建表 执行一条sql语句 增删改 都是这样的 查询比较特殊 NSString *sqlStr = @"CREATE TABLE IF NOT EXISTS t_test (ID INTEGER PRIMARY KEY AUTOINCREMENT ,NAME TEXT ,AGE INTEGER );"; BOOL successT = [self.db executeUpdate:sqlStr]; if (successT) { NSLog(@"创建表成功!"); }else{ NSLog(@"创建表失败!"); } }else{ NSLog(@"数据库创建失败!"); } NSLog(@"%@",NSHomeDirectory()); //关闭数据库 //sqlite3_close(_db);}//增加数据- (void)addFMDB { [self.db beginTransaction]; BOOL isRollBack = NO; @try { //往表中循环插入100条数据 for (int i = 0; i < 50000 ; i++) { //名称设置为J_mailbox NSString *name = [NSString stringWithFormat:@"J_mailbox-%d",i]; //随机生成20岁~25岁之间的记录 NSInteger age = arc4random_uniform(5) + 20; //sql插入语句的拼接 NSString *resultStr = [NSString stringWithFormat:@"INSERT INTO t_test (NAME,AGE) VALUES('%@',%zd) ",name,age]; //执行sql插入语句(调用FMDB对象方法) BOOL success = [self.db executeUpdate:resultStr]; //判断是否添加成功// if (success) {// NSLog(@"添加数据成功!");// }else{// NSLog(@"添加数据失败!");// } } } @catch (NSException *exception) { isRollBack = YES; [self.db rollback]; } @finally { if (!isRollBack) { [self.db commit]; NSLog(@"最终成功"); } }}//删除数据- (void)deleteFMDB { //删除语句 NSString *sqlStr = @"DELETE FROM t_test WHERE AGE > 19 ;"; //执行sql删除语句(调用FMDB对象方法) BOOL success = [self.db executeUpdate:sqlStr]; if (success) { NSLog(@"删除数据成功!"); }else{ NSLog(@"删除数据失败!"); }}//修改数据- (void)changeFMDB{ //修改语句 NSString *sqlStr = @"UPDATE t_test SET AGE = 30 WHERE AGE > 19;"; //执行sql修改语句(调用FMDB对象方法) BOOL success = [self.db executeUpdate:sqlStr]; if (success) { NSLog(@"修改数据成功!"); }else{ NSLog(@"修改数据失败!"); } }//查询数据- (void)queryFMDB { //查询语句 NSString *sqlStr = @"SELECT NAME,AGE FROM t_test WHERE AGE > 19;"; //执行sql查询语句(调用FMDB对象方法) FMResultSet *set = [self.db executeQuery:sqlStr]; while ([set next]) { //等价于 == sqlite_Row //NAME NSString *name = [set stringForColumnIndex:0]; //AGE NSInteger age = [set intForColumnIndex:1]; NSLog(@"NAME = %@ AGE = %ld",name,(long)age); } }- (void)initUI{ CGFloat x = 50,y = 50; UILabel *fmdbLabel = [[UILabel alloc] initWithFrame:CGRectMake(x, y, 10, 10)]; fmdbLabel.text = @"fmdb"; [fmdbLabel sizeToFit]; [self.view addSubview:fmdbLabel]; x -= 5; y += 50; UIButton *addBtn = [[UIButton alloc] initWithFrame:CGRectMake(x, y, 10, 10)]; [addBtn setTitle:@"add" forState:UIControlStateNormal]; [addBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; addBtn.tag = 0; [addBtn addTarget:self action:@selector(operetionClick:) forControlEvents:UIControlEventTouchUpInside]; [addBtn sizeToFit]; [self.view addSubview:addBtn]; y += 50; UIButton *deleteBtn = [[UIButton alloc] initWithFrame:CGRectMake(x, y, 10, 10)]; [deleteBtn setTitle:@"delete" forState:UIControlStateNormal]; [deleteBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; deleteBtn.tag = 1; [deleteBtn addTarget:self action:@selector(operetionClick:) forControlEvents:UIControlEventTouchUpInside]; [deleteBtn sizeToFit]; [self.view addSubview:deleteBtn]; y += 50; UIButton *changeBtn = [[UIButton alloc] initWithFrame:CGRectMake(x, y, 10, 10)]; [changeBtn setTitle:@"change" forState:UIControlStateNormal]; [changeBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; changeBtn.tag = 2; [changeBtn addTarget:self action:@selector(operetionClick:) forControlEvents:UIControlEventTouchUpInside]; [changeBtn sizeToFit]; [self.view addSubview:changeBtn]; y += 50; UIButton *queryBtn = [[UIButton alloc] initWithFrame:CGRectMake(x, y, 10, 10)]; [queryBtn setTitle:@"query" forState:UIControlStateNormal]; [queryBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; queryBtn.tag = 3; [queryBtn addTarget:self action:@selector(operetionClick:) forControlEvents:UIControlEventTouchUpInside]; [queryBtn sizeToFit]; [self.view addSubview:queryBtn]; //Core Data x = 200,y = 50; UILabel *coreDataLabel = [[UILabel alloc] initWithFrame:CGRectMake(x, y, 10, 10)]; coreDataLabel.text = @"coreData"; [coreDataLabel sizeToFit]; [self.view addSubview:coreDataLabel]; x -= 5; y += 50; UIButton *addBtn1 = [[UIButton alloc] initWithFrame:CGRectMake(x, y, 10, 10)]; [addBtn1 setTitle:@"add" forState:UIControlStateNormal]; [addBtn1 setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; addBtn1.tag = 4; [addBtn1 addTarget:self action:@selector(operetionClick:) forControlEvents:UIControlEventTouchUpInside]; [addBtn1 sizeToFit]; [self.view addSubview:addBtn1]; y += 50; UIButton *deleteBtn1 = [[UIButton alloc] initWithFrame:CGRectMake(x, y, 10, 10)]; [deleteBtn1 setTitle:@"delete" forState:UIControlStateNormal]; [deleteBtn1 setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; deleteBtn1.tag = 5; [deleteBtn1 addTarget:self action:@selector(operetionClick:) forControlEvents:UIControlEventTouchUpInside]; [deleteBtn1 sizeToFit]; [self.view addSubview:deleteBtn1]; y += 50; UIButton *changeBtn1 = [[UIButton alloc] initWithFrame:CGRectMake(x, y, 10, 10)]; [changeBtn1 setTitle:@"change" forState:UIControlStateNormal]; [changeBtn1 setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; changeBtn1.tag = 6; [changeBtn1 addTarget:self action:@selector(operetionClick:) forControlEvents:UIControlEventTouchUpInside]; [changeBtn1 sizeToFit]; [self.view addSubview:changeBtn1]; y += 50; UIButton *queryBtn1 = [[UIButton alloc] initWithFrame:CGRectMake(x, y, 10, 10)]; [queryBtn1 setTitle:@"query" forState:UIControlStateNormal]; [queryBtn1 setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; queryBtn1.tag = 7; [queryBtn1 addTarget:self action:@selector(operetionClick:) forControlEvents:UIControlEventTouchUpInside]; [queryBtn1 sizeToFit]; [self.view addSubview:queryBtn1];}@end
阅读全文
0 0
- ios CoreData和FMDB最新使用问题总结
- 【iOS开发】数据存储之coredata、sqlite、fmdb和sqlitepersistentobject
- iOS 数据库-SQLite3 CoreData FMDB
- (IOS)sqlcipher和FMDB的使用总结(原创)
- coredata、sqlite、fmdb和sqlitepersistentobject
- iOS-SQLite3和FMDB使用
- iOS-SQLite3和FMDB使用
- iOS-FMDB和SQLite3使用
- iOS SQLite、CoreData、FMDB数据库详解
- 【数据存储】coredata、sqlite、fmdb和sqlitepersistentobject
- iOS CoreData的使用和简介
- iOS FMDB的使用
- IOS FMDB 使用
- iOS FMDB使用
- iOS开发 ----- FMDB使用
- iOS FMDB的使用
- IOS Sqlite使用FMDB
- Ios fmdb的使用
- Java 实例
- leetcode 117. Populating Next Right Pointers in Each Node II
- js获得时间参数
- 投资风口再起:医疗机器人成为热点
- StringUtils.isEmpty和StringUtils.isBlank用法和区别
- ios CoreData和FMDB最新使用问题总结
- js控制textarea禁止输入表情
- Angular2-使用Angular CLI快速搭建工程(一)
- Java特性封装
- h5储存和cookie储存
- arcgis web 显示加载arcgis server地图,提供查询标记功能
- 安装opencv出现常见问题的解决办法
- HTML学习---------1.4认识html文件的基本结构
- 南阳理工acm 47过河问题(贪心+排序)