一、前言
如上一章所讲,FMDB源码主要有以下几个文件组成:
FMResultSet : 表示FMDatabase执行查询之后的结果集。
FMDatabase : 表示一个单独的SQLite数据库操作实例,通过它可以对数据库进行增删改查等等操作。
FMDatabaseAdditions : 扩展FMDatabase类,新增对查询结果只返回单个值的方法进行简化,对表、列是否存在,版本号,校验SQL等等功能。
FMDatabaseQueue : 使用串行队列 ,对多线程的操作进行了支持。
FMDatabasePool : 使用任务池的形式,对多线程的操作提供支持。(不过官方对这种方式并不推荐使用,优先选择FMDatabaseQueue的方式:ONLY_USE_THE_POOL_IF_YOU_ARE_DOING_READS_OTHERWISE_YOULL_DEADLOCK_USE_FMDATABASEQUEUE_INSTEAD)
FMDB比较优秀的地方就在于对多线程的处理。所以这一篇主要是研究FMDB的多线程处理的实现。而FMDB最新的版本中主要是通过使用FMDatabaseQueue这个类来进行多线程处理的。
二、FMDatabaseQueue源码分析
我们先来看看FMDatabaseQueue如何使用。
/**
* FMDatabaseQueue使用案例
*/
- (void)FMDatabaseQueueTest{
//1、获取数据库文件路径
NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *fileName = [doc stringByAppendingPathComponent:@"students.sqlite"];
//使用
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:fileName];
[queue inDatabase:^(FMDatabase *db) {
[db executeUpdate:@"CREATE TABLE IF NOT EXISTS t_student_2 (id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL, age integer NOT NULL);"];
[db executeUpdate:@"INSERT INTO t_student_2 (name, age) VALUES ('yixiangZZ', 20);"];
[db executeUpdate:@"INSERT INTO t_student_2 (name, age) VALUES ('yixiangXX', 25);"];
FMResultSet *rs = [db executeQuery:@"SELECT * FROM t_student_2"];
NSLog(@"%@",[NSThread currentThread]);
while ([rs next]) {
int ID = [rs intForColumn:@"id"];
NSString *name = [rs stringForColumn:@"name"];
int age = [rs intForColumn:@"age"];
NSLog(@"%d %@ %d",ID,name,age);
}
}];
//支持事务
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
[db executeUpdate:@"UPDATE t_student_2 SET age = 40 WHERE name = 'yixiangZZ'"];
[db executeUpdate:@"UPDATE t_student_2 SET age = 45 WHERE name = 'yixiangXX'"];
BOOL hasProblem = NO;
if (hasProblem) {
*rollback = YES;//回滚
return;
}
FMResultSet *rs = [db executeQuery:@"SELECT * FROM t_student_2"];
NSLog(@"%@",[NSThread currentThread]);
while ([rs next]) {
int ID = [rs intForColumn:@"id"];
NSString *name = [rs stringForColumn:@"name"];
int age = [rs intForColumn:@"age"];
NSLog(@"%d %@ %d",ID,name,age);
}
}];
}
F