FMDB-FMDatabaseQueue
FMDB封装了SQLite3的方法,操作数据库变得很简单。
增删改查变简单之后,那么问题来了,如何使用多线程优化对数据库的操作?
这是我们的第一反应估计是dispatch_async().
那么问题又来了,多线程操作如何防止database被lock?
哇哈哈,这个时候就要用到FMDatabaseQueue。
先来了解下FMDatabaseQueue的用法。
先来建个表热热身
- NSString* path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/test.db"];
- NSLog(@"path = %@",path);
- self.dbQueue = [FMDatabaseQueue databaseQueueWithPath:path];
- [self.dbQueue inDatabase:^(FMDatabase *db) {
- BOOL result = [db executeUpdate:@"create table if not exists testTable (id integer PRIMARY KEY AUTOINCREMENT, name text)"];
- NSLog(@"creare %@",result?@"success":@"fail");
- }];
没错,就是这么的简单。
那么再来插入几条数据
- [self.dbQueue inDatabase:^(FMDatabase *db) {
- for (int i = 0; i < 500; i++) {
- [db executeUpdate:@"insert into testTable (name) values(?)",[NSString stringWithFormat:@"name-%d",i]];
- }
- }];
恩,很帅气有木有。
开启事务,再插入一次
- [self.dbQueue inTransaction:^(FMDatabase *db, BOOLBOOL *rollback) {
- BOOL result = YES;
- for (int i = 500; i < 1000; i++) {
- result = [db executeUpdate:@"insert into testTable (name) values(?)",[NSString stringWithFormat:@"name-%d",i]];
- if (!result) {
- NSLog(@"break");
- *rollback = YES;
- break;
- }
- }
- }];
对比下效率:
- NSDate* one = [NSDate date];
- [self.dbQueue inDatabase:^(FMDatabase *db) {
- for (int i = 0; i < 500; i++) {
- [db executeUpdate:@"insert into testTable (name) values(?)",[NSString stringWithFormat:@"name-%d",i]];
- }
- }];
- NSDate* two = [NSDate date];
- NSTimeInterval first = [two timeIntervalSinceDate:one];
- NSLog(@"first = %lf",first);
- NSDate* three = [NSDate date];
- [self.dbQueue inTransaction:^(FMDatabase *db, BOOLBOOL *rollback) {
- BOOL result = YES;
- for (int i = 500; i < 1000; i++) {
- result = [db executeUpdate:@"insert into testTable (name) values(?)",[NSString stringWithFormat:@"name-%d",i]];
- if (!result) {
- NSLog(@"break");
- *rollback = YES;
- break;
- }
- }
- }];
- NSDate* four = [NSDate date];
- NSTimeInterval second = [four timeIntervalSinceDate:three];
- NSLog(@"second = %lf",second);
输出打印:
- 2014-11-18 22:01:57.756 FMDB[7489:230565] path = /Users/zhutc/Library/Developer/CoreSimulator/Devices/9001525C-7201-480E-ADC8-8F77C160A18F/data/Containers/Data/Application/6D0C0AE6-3069-4BEE-A7B9-1161C73540BD/Documents/test.db
- 2014-11-18 22:01:57.759 FMDB[7489:230565] creare success
- 2014-11-18 22:02:03.029 FMDB[7489:230565] first = 5.270233
- 2014-11-18 22:02:03.052 FMDB[7489:230565] second = 0.022609
再看看删除:
- NSDate* five = [NSDate date];
- [self.dbQueue inDatabase:^(FMDatabase *db) {
- [db executeUpdate:@"delete from testTable where id < 500"];
- }];
- NSDate* six = [NSDate date];
- NSTimeInterval third = [six timeIntervalSinceDate:five];
- NSLog(@"third = %lf",third);
- NSDate* seven = [NSDate date];
- [self.dbQueue inTransaction:^(FMDatabase *db, BOOLBOOL *rollback) {
- [db executeUpdate:@"delete from testTable where id >= 500"];
- }];
- NSDate* eight = [NSDate date];
- NSTimeInterval fourth = [eight timeIntervalSinceDate:seven];
- NSLog(@"fourth = %lf",fourth);
看看打印:
- 2014-11-18 22:02:03.066 FMDB[7489:230565] third = 0.013382
- 2014-11-18 22:02:03.080 FMDB[7489:230565] fourth = 0.013715
还是事务高大上!!!
可以看出来:使用事务处理就是将所有任务执行完成以后将结果一次性提交到数据库,如果此过程出现异常则会执行回滚操作,这样节省了大量的重复提交环节所浪费的时间。
多线程在哪里?
看下FMDatabaseQueue的源码,发现了一个串行的queue,而且这个queue是同步调用
这个源码是比较老得,最新版的没下载下来,就拿过来用用。最新版的变动是使用同一个queue,可重入。
- - (void)inDatabase:(void (^)(FMDatabase *db))block {
- FMDBRetain(self);
- dispatch_sync(_queue, ^() {
- FMDatabase *db = [self database];
- block(db);
- if ([db hasOpenResultSets]) {
- NSLog(@"Warning: there is at least one open result set around after performing [FMDatabaseQueue inDatabase:]");
- }
- });
- FMDBRelease(self);
- }
到这里应该就知道,我们只需要使用dispatch_async,然后配合FMDatabaseQueue。
- dispatch_async(dispatch_get_global_queue(0, 0), ^{
- [self.dbQueue inTransaction:^(FMDatabase *db, BOOLBOOL *rollback) {
- BOOL result = YES;
- for (int i = 500; i < 1000; i++) {
- result = [db executeUpdate:@"insert into testTable (name) values(?)",[NSString stringWithFormat:@"name-%d",i]];
- if (!result) {
- NSLog(@"break");
- *rollback = YES;
- break;
- }
- }
- }];
- });
最新版的FMDB不可以在多个队列中使用同一个FMDatabaseQueue实例,会有问题。至于为毛,等研究透了在补充。哇哈哈!1
FMDB-FMDatabaseQueue的更多相关文章
- FMDB多线程读写问题,使用FMDataBaseQueue操作可以解决同时打开一个链接de读写问题
现在ios里使用的数据库一般都是Sqlite,但是使用Sqlite有个不太好的地方就是在多线程的时候,会出现问题,sqlite只能打开一个读或者写连结.这样的话多线程就会碰到资源占用的问题. 最开始是 ...
- 【原】FMDB源码阅读(三)
[原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...
- FMDB的使用方法
转自:http://blog.devtang.com/blog/2012/04/22/use-fmdb/ 前言 SQLite (http://www.sqlite.org/docs.html) 是一个 ...
- FMDB 排它锁
-------------------------------------基本操作------------------------------------- #import "ViewCon ...
- IOS数据存储之FMDB数据库
前言: 最近几天一直在折腾数据库存储,之前文章(http://www.cnblogs.com/whoislcj/p/5485959.html)介绍了Sqlite 数据库,SQLite是一种小型的轻量级 ...
- FMDB第三方框架
FMDB是同AFN,SDWebImage同样好用的第三方框架,它以OC的方式封装了SQLite的C语言API,使得开发变得简单方便. 附上github链接https://github.com/ccgu ...
- FMDB 数据库
iOS中原生的SQLite API在使用上相当不友好,在使用时,非常不便.于是,就出现了一系列将SQLite API进行封装的库,例如FMDB.PlausibleDatabase.sqlitepers ...
- 【原】iOS学习47之第三方-FMDB
将 CocoaPods 安装后,按照 CocoaPods 的使用说明就可以将 FMDB 第三方集成到工程中,具体请看博客iOS学习46之第三方CocoaPods的安装和使用(通用方法) 1. FMDB ...
- FMDB
一.FMDB简介 1.FMDB简介 iOS中原生的SQLite API在进行数据存储的时候,需要使用C语言中的函数,操作比较繁琐.于是,就出现了一系列将SQLite API进行封装的库,例如FMDB. ...
- FMDB浅析
一.FMDB介绍 FMDB是一种第三方的开源库,FMDB就是对SQLite的API进行了封装,加上了面向对象的思想,让我们不必使用繁琐的C语言API函数,比起直接操作SQLite更加方便. FMDB优 ...
随机推荐
- LeetCode 60. 第k个排列(Permutation Sequence)
题目描述 给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列. 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下: "123" "1 ...
- DAY 5模拟赛
DAY 5 廖俊豪神仙出题 T1 最小差异矩阵(a.cpp, a.in, a.out) [题目描述] 有一个 n*m 的矩阵,矩阵的每个位置上可以放置一个数.对于第 i 行,第 i 行的差异定义为该行 ...
- AI换脸必备知识:如何查看显卡型号以及显存大小!
使用Deepfakes(AI换脸) 软件,拼的就是配置,耗的就是时间,考验的是耐心. 配置好了,时间就少了. 所以玩这种软件,硬核需求就是:配置,配置,配置. 我的电脑能跑这个软件么?也是很多新手的 ...
- Eclipse如何安装Fat Jar
〇.安装前准备 1.Fat Jar插件下载地址:https://sourceforge.net/projects/fjep/files/ 2.安装前请确认Eclipse版本:Help --> A ...
- [mysql]设置创建时间,更新时间未生效
问题描述: 新增一条case,create_time没有自动生成创建时间,值为空 原因 : create_time字段类型是DateTime(错误)而不是TIMESTAMP(正确) 解决办法: 把c ...
- EMQTT测试--安装与测试 (windows)
我下载的是windows版 安装 参考http://emqtt.com/docs/install.html 将下载的压缩包解压,我解压到了D盘 命令行窗口,cd到程序目录 控制台模式启动: .\bin ...
- 利用Python处理向不受信任主机发送请求
,HTTP vs HTTPS 超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息.HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器 ...
- oracle 创建多个数据库
1. 2. 3. 4. 5. 6. 7.监听程序 8.后面的我全选择默认(脚本位自定义了一下) 9.
- 阶段3 2.Spring_10.Spring中事务控制_4 spring中事务控制的一组API
分析aop的 xml 的代码.更直观一些 事务提交和回滚就是我们重复的代码 spring业余事务管理器,我们拿过来直接用就可以 提交和回滚的后面直接调用释放.所以释放资源之类就是多余的 在绑定连接到线 ...
- 十三:jinja2过滤器之default过滤器和or过滤器
在模板里面有时候需要对传过来的数据进行一些处理,jinja2有一些内置的过滤器可以进行处理.类似于python内置函数,通过 “|” 进行使用,详见jinja2官方文档 使用方法:{{ 变量名|过滤器 ...