FMDB使用札记
前言
FMDB 是一款使用Objective-C对SQLite进行封装的优秀的第三方框架,加上了面向对象的思想。
优点:
- 使用起来更加面向对象,省去了很多麻烦、冗余的C语言代码
- 对比苹果自带的CoreData框架,更加轻量级和灵活
- 提供多线程安全,有效地防止数据混乱,原来的SQLite不是线程安全的
- 支持使用Swift调用
缺点:
- 因为是OC语言封装的,失去了SQLite原来的跨平台性
FMDB的方方面面在Github上已经交代的比较明白,这里自己再总结摘要一下。
安装
- 在Github上下载FMBDB源码,将文件拖入工程
- 在项目target的Build Phases->Link Bianry With Libraries中添加libsqlite3.tbd依赖库
- #import “FMDatabase.h”
使用
主要包含如下三个类: - FMDatabase - 代表一个SQLite数据库,用来在单一线程中执行SQL语句,线程不安全。
- FMResultSet - 代表执行一次查询后的结果。
- FMDatabaseQueue - 用于多线程操作数据库的查询和更新,线程安全。
创建数据库
支持传入3种文件路径:
- 传入真实的文件系统路径,如不存在该文件,将自动创建;
- 传入空字符串@””. 创建一个本地的临时数据库,当FMDatabase连接关掉后将被自动删除;
- 传入NULL.创建一个in-memory数据库,当FMDatabase连接关掉后将被自动释放。
|
|
打开数据库
在使用之前,必须先调用open函数,保证数据库被打开。当资源不足或权限不够时,可能会open失败,这时需要返回,无法后续操作。
|
|
执行更新
任何不以SELECT开头的SQL操作都属于更新操作,包括 CREATE, UPDATE, INSERT, ALTER, COMMIT, BEGIN, DETACH, DELETE, DROP, END, EXPLAIN, VACUUM, 以及 REPLACE 等,通过-executeUpate...
这种方法来执行,执行更新正确会返回YES,否则返回NO。
|
|
执行查询
一个SELECT查询语句将通过-executeQuery...
这种方法来执行,如果正确,返回一个FMResultSet对象,否则返回nil。必须使用-lastErrorMessage和-lastErrorCode方法来查询为何执行失败。
|
|
关闭数据库
调用close方法即可。
事务
事务,是指作为单个逻辑工作单元执行的一系列操作,要么完整地执行,要么完全地不执行。
想象一个场景,比如你要更新数据库的大量数据,我们需要确保所有的数据更新成功,才采取这种更新方案,如果在更新期间出现错误,就不能采取这种更新方案了,如果我们不使用事务,我们的更新操作直接对每个记录生效,万一遇到更新错误,已经更新的数据怎么办?难道我们要一个一个去找出来修改回来吗?怎么知道原来的数据是怎么样的呢?这个时候就需要使用事务实现。
SQLite进行事务处理:
- 只要在执行SQL语句前加上以下的SQL语句,就可以使用事务功能了:
- 开启事务的SQL语句,”begin transaction;”
- 进行提交的SQL语句,”commit transaction;”
- 进行回滚的SQL语句,”rollback transaction;”
FMDatabase使用事务:
使用线程安全的FMDatabaseQueue
不能在线程间共用一个FMDatabase, 否则会造成数据混乱! 如果需要使用多线程,应该使用线程安全的FMDatabaseQueue. (#import “FMDatabaseQueue.h” 即可)
FMDatabaseQueue的操作与FMDatabase非常类似,如
- 创建
FMDatabaseQueue* queue = [FMDatabaseQueue databaseQueueWithPath: aPath];
操作
将FMDatabase中的操作放到
123[queue inDatabase:^(FMdatabase*db){//FMDatabase操作}];
即可。
|
|
事务
123456789101112131415161718//多线程事务- (void)transactionByQueue {//开启事务[self.queue inTransaction:^(FMDatabase *db, BOOL *rollback) {for (int i = 0; i<500; i++) {NSNumber *num = @(i+1);NSString *name = [[NSString alloc] initWithFormat:@"student_%d",i];NSString *sex = (i%2==0)?@"f":@"m";NSString *sql = @"insert into mytable(num,name,sex) values(?,?,?);";BOOL result = [db executeUpdate:sql,num,name,sex];if ( !result ) {//当最后*rollback的值为YES的时候,事务回退,如果最后*rollback为NO,事务提交*rollback = YES;return;}}}];}