FMDB-FMDatabaseQueue
来源:互联网 发布:日本对外贸易数据 编辑:程序博客网 时间:2024/06/05 16:45
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;
- }
- }
- }];
- });
阅读全文
0 0
- FMDB-FMDatabaseQueue
- FMDB-FMDatabaseQueue
- FMDB使用Queue:FMDatabaseQueue
- FMDatabaseQueue
- FMDB的使用,如何利用FMDatabaseQueue保证线程安全
- 【iOS开发-105】SQLite第三方框架FMDB的使用,以及使用FMDatabaseQueue保证线程安全
- IOS开发源码阅读篇--FMDB源码分析3(FMDatabaseQueue+FMDatabasePool)
- FMDatabaseQueue 使用
- FMDB
- FMDB
- FMDB
- FMDB
- FMDB
- fmdb
- FMDB
- FMDB
- fmdb
- FMDB
- 1024
- Linux下AdobeMediaServer5推流测试
- linux设备和驱动加载的先后顺序
- 前后端分离,nginx配置解决js、css无法加载
- JDBC中对PreparedStatement的理解对数据库自动生成的主键值的获取
- FMDB-FMDatabaseQueue
- 归并排序
- ubuntu 按Tab补全报错
- Java_快速排序
- 机器学习算法 原理、实现与实践 —— 距离的度量
- 机器学习评估指标总结
- codeblock手动添加C++11标准
- 缓存数据库
- C++&Python——【USACO 5.4.1】——Canada Tour