版权声明:本文为博主原创文章,未经博主允许不得转载。
iOS开发常用的存储方案有两种 1)使用基于sqlite的开源框架 2)使用苹果官方的coredata。这里不讨论两类存储方式的区别,主要谈一谈基于sqlit的fmdb框架。
原生的sqlite使用上相当不友好,而且还需要自己去控制多线程的访问,比较麻烦,fmdb因其友好的api,安全的多线程操作以及大量的开源人员的维护成为了开源社区的佼佼者。
由于fmdb本质上是对sqlite api以及多线程的封装,这里是源码链接https://github.com/ccgus/fmdb。将fmdb引入项目,只需要把这些文件引入进来即可。
1.单线程环境下
最简单的fmdb使用,可以直接使用fmdatabase,这个时候一定要记得手动开启、关闭db。基本api如下
1)创建
FMDatabase *db = [FMDatabase databaseWithPath:@"88888"];
2)打开
[db open])
3)查询
FMResultSet *s = [db executeQuery:@"SELECT * FROM myTable"];
while ([s next]) {
//retrieve values for each record
}
4)插入,删除,更新
BOOL res = [db executeUpdate:sql, @"""];
5)关闭连接[db close];
2)多线程环境下
单个fmdatabase实例不能在多线程环境下被使用,因为它本身并不是线程安全的,因此在多线程的情况下,需要使用fmdb提供的多线程接口fmdatabasequeue
使用fmdatabasequeue进行多线程编程,
这里的queue,其实是在里面封装了一个顺序队列,确保一个时刻只有一个线程在使用db实例,这一点在fmdatabasequeue.m源码中可以看见
而且在使用queue的时候,我们不需要每次都手动的去open以及close db,从上面截图可以看到,queue已经帮我们打开open db,至于close操作,通常是在我们不再使用queue的时候执行
但是有一点需要注意的事,即使你使用了fmdatabasequeue,在多线程环境下也要注意,如果你在不同的线程里面调用了fmdatabasequeue,且不同线程,或者队列分别生成了自己的fmdatabasequeue,那么,本质上,你还是会建立多个fmdatabase的连接,这样还是有可能发生死锁等问题,因此在实际使用中,最后将fmdatabasequeue单例化。
3、事务
fmdb同时还提供了事务的支持,基本跟上面的用法差不多,使用如下,这是官网上的一个例子
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) { [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]]; [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]]; [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]]; if (whoopsSomethingWrongHappened) { *rollback = YES; return; } // etc… [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]]; }];