iOS开发中存储大批量数据的时候一般都会用SQLite或者CoreData,如果我们选择SQLite的话那么有一个很好用的工具就是FMDB
iOS上的SQLite是一套纯C的框架,使用起来不是那么友好.其实github上有好多封装的SQLite框架,而FMDB则是他们之中最优秀的~
FMDB的地址: https://github.com/ccgus/fmdb
使用FMDB很简单
FMDatabase * db = [FMDatabase databaseWithPath:self.dbPath];
上面这么一句话就可以创建或者打开一个数据库文件了,但是最好在打开之前看一下你定义的路径文件是否已经存在,以免发生不必要的错误
NSFileManager * fileManager = [NSFileManager defaultManager]; if ([fileManager fileExistsAtPath:self.dbPath] == NO) {.....}
下面是一段完整的创建代码
NSFileManager * fileManager = [NSFileManager defaultManager]; if ([fileManager fileExistsAtPath:self.dbPath] == NO) { // create it FMDatabase * db = [FMDatabase databaseWithPath:self.dbPath]; if ([db open]) { NSString * sql = @"CREATE TABLE ‘User‘ (‘id‘ INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , ‘name‘ VARCHAR(30), ‘password‘ VARCHAR(30))"; BOOL res = [db executeUpdate:sql]; if (!res) { debugLog(@"error when creating db table"); } else { debugLog(@"succ to creating db table"); } [db close]; } else { debugLog(@"error when open db"); } }
使用FMDB要记得使用完之后一定要调用close方法进行关闭
下面是一段插入数据的代码
static int idx = 1; FMDatabase * db = [FMDatabase databaseWithPath:self.dbPath]; if ([db open]) { NSString * sql = @"insert into user (name, password) values(?, ?) "; NSString * name = [NSString stringWithFormat:@"tangqiao%d", idx++]; BOOL res = [db executeUpdate:sql, name, @"boy"]; if (!res) { debugLog(@"error to insert data"); } else { debugLog(@"succ to insert data"); } [db close]; }
插入数据时可以用?当占位符使用,不用去拼接字符串,但是这里的占位参数智能接收NSObject继承体系里面的类,所以如果你传的是int double等这些类型需要用对应的对象包装一下.或者用字面量语法包装一下也可以
下面是一段查询代码,查询数据时要用到FMResultSet
FMDatabase * db = [FMDatabase databaseWithPath:self.dbPath]; if ([db open]) { NSString * sql = @"select * from user"; FMResultSet * rs = [db executeQuery:sql]; while ([rs next]) { int userId = [rs intForColumn:@"id"]; NSString * name = [rs stringForColumn:@"name"]; NSString * pass = [rs stringForColumn:@"password"]; debugLog(@"user id = %d, name = %@, pass = %@", userId, name, pass); } [db close]; }
下面是一段删除数据的代码
FMDatabase * db = [FMDatabase databaseWithPath:self.dbPath]; if ([db open]) { NSString * sql = @"delete from user"; BOOL res = [db executeUpdate:sql]; if (!res) { debugLog(@"error to delete db data"); } else { debugLog(@"succ to deleta db data"); } [db close]; }
从上面可以看出查询数据执行的是executeQuery:方法,其他的都是executeUpdate:方法
FMDataBase对象不是线程安全的,如果你要在做个线程里操作数据库,那么切记不要使用同一个FMDataBase对象
使用FMDatabaseQueue可以保证线程安全,下面是一段使用代码
FMDatabaseQueue * queue = [FMDatabaseQueue databaseQueueWithPath:self.dbPath]; dispatch_queue_t q1 = dispatch_queue_create("queue1", NULL); dispatch_queue_t q2 = dispatch_queue_create("queue2", NULL); dispatch_async(q1, ^{ for (int i = 0; i < 100; ++i) { [queue inDatabase:^(FMDatabase *db) { NSString * sql = @"insert into user (name, password) values(?, ?) "; NSString * name = [NSString stringWithFormat:@"queue111 %d", i]; BOOL res = [db executeUpdate:sql, name, @"boy"]; if (!res) { debugLog(@"error to add db data: %@", name); } else { debugLog(@"succ to add db data: %@", name); } }]; } }); dispatch_async(q2, ^{ for (int i = 0; i < 100; ++i) { [queue inDatabase:^(FMDatabase *db) { NSString * sql = @"insert into user (name, password) values(?, ?) "; NSString * name = [NSString stringWithFormat:@"queue222 %d", i]; BOOL res = [db executeUpdate:sql, name, @"boy"]; if (!res) { debugLog(@"error to add db data: %@", name); } else { debugLog(@"succ to add db data: %@", name); } }]; } });
用一个路径来初始化FMDatabaseQueue,然后就可以安全的使用多线程操作了
下面是唐巧博客讲FMBD的地址,我上面代码来自唐巧的DEMO(公司项目里面的代码太多,而且贴出来不太好,所以就用的唐大婶的),想更深的了解FMDB,需要去看FMDB的文档~
http://blog.devtang.com/blog/2012/04/22/use-fmdb/