chenzhao

  • java
  • iOS
  • IT
知识积累
不积跬步无以至千里
  1. 首页
  2. iOS
  3. 正文

FMDB使用札记

2017年 11月 9日 86点热度 0人点赞 0条评论

From: http://vin-zhou.github.io/2016/11/18/FMDB%E4%BD%BF%E7%94%A8%E6%9C%AD%E8%AE%B0/

文章目录

    1. 前言
    1. 安装
    1. 使用
    1. 创建数据库
    1. 打开数据库
      1. 5.1. 执行更新
    1. 执行查询
    1. 关闭数据库
    1. 事务
    1. 使用线程安全的FMDatabaseQueue
    1. 参考

前言

[FMDB][1] 是一款使用Objective-C对SQLite进行封装的优秀的第三方框架,加上了面向对象的思想。

[1]:

优点:

  • 使用起来更加面向对象,省去了很多麻烦、冗余的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连接关掉后将被自动释放。

NSArray* array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 

NSString* documents = [array objectAtIndex:0]; 

NSString* path = [documents stringByAppendingPathComponent:@"test.db"]; 

FMDatabase* db = [FMDatabase databaseWithPath:path]; 

打开数据库

在使用之前,必须先调用open函数,保证数据库被打开。当资源不足或权限不够时,可能会open失败,这时需要返回,无法后续操作。

if (![db open]) { 

db = nil; 

return; 

} 

执行更新

任何不以SELECT开头的SQL操作都属于更新操作,包括 CREATE, UPDATE, INSERT, ALTER, COMMIT, BEGIN, DETACH, DELETE, DROP, END, EXPLAIN, VACUUM, 以及 REPLACE 等,通过-executeUpate...这种方法来执行,执行更新正确会返回YES,否则返回NO。

BOOL updateResult = [db executeUpdate:@"CREATE TABLE myTable (num integer, name varchar(7), sex char(1), primary key(num))"]; 

if (!updateResult) {return;} 

updateResult = [db executeUpdate:@"INSERT INTO myTable(num, name, sex) values(?,?,?)", @0, @"hha", @"m"]; 

执行查询

一个SELECT查询语句将通过-executeQuery...这种方法来执行,如果正确,返回一个FMResultSet对象,否则返回nil。必须使用-lastErrorMessage和-lastErrorCode方法来查询为何执行失败。

FMResultSet* result = [db executeQuery:@"SELECT * FROM myTable"]; 

NSMutableArray *array = [NSMutableArray array]; 

while ([result next]) { 

NSMutableDictionary *dict = [NSMutableDictionary dictionary]; 

int num = [result intForColumn:@"num"]; 

NSString *name = [result stringForColumn:@"name"]; 

NSString *sex = [result stringForColumn:@"sex"]; 

dict[@"num"] = @(num); 

dict[@"name"] = name; 

dict[@"sex"] = sex; 

[array addObject:dict]; 

} 

关闭数据库

调用close方法即可。

事务

事务,是指作为单个逻辑工作单元执行的一系列操作,要么完整地执行,要么完全地不执行。
想象一个场景,比如你要更新数据库的大量数据,我们需要确保所有的数据更新成功,才采取这种更新方案,如果在更新期间出现错误,就不能采取这种更新方案了,如果我们不使用事务,我们的更新操作直接对每个记录生效,万一遇到更新错误,已经更新的数据怎么办?难道我们要一个一个去找出来修改回来吗?怎么知道原来的数据是怎么样的呢?这个时候就需要使用事务实现。

SQLite进行事务处理:

  • 只要在执行SQL语句前加上以下的SQL语句,就可以使用事务功能了:
  • 开启事务的SQL语句,”begin transaction;”
  • 进行提交的SQL语句,”commit transaction;”
  • 进行回滚的SQL语句,”rollback transaction;”

FMDatabase使用事务:


-(void)transaction { 

[self.database beginTransaction]; 

BOOL isRollBack = NO; 

@try { 

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 = [database executeUpdate:sql,num,name,sex]; 

if ( !result ) { 

NSLog(@"插入失败!"); 

return; 

} 

} 

} 

@catch (NSException *exception) { 

isRollBack = YES; 

[self.database rollback]; 

} 

@finally { 

if (!isRollBack) { 

[self.database commit]; 

} 

} 

} 

使用线程安全的FMDatabaseQueue

不能在线程间共用一个FMDatabase, 否则会造成数据混乱! 如果需要使用多线程,应该使用线程安全的FMDatabaseQueue. (#import “FMDatabaseQueue.h” 即可)
FMDatabaseQueue的操作与FMDatabase非常类似,如

  • 创建
    FMDatabaseQueue* queue = [FMDatabaseQueue databaseQueueWithPath: aPath];
  • 操作

将FMDatabase中的操作放到

[queue inDatabase:^(FMdatabase*db){ 

}];


即可。 


[queue inDatabase:^(FMDatabase*db) { 

NSString *sqlStr = @"insert into mytable(num,name,sex) values(4,'xiaoming','m');"; 

BOOL result = [db executeUpdate:sqlStr]; 

if (!result) { 

NSLog(@"error when insert into database table"); 

[db close]; 

} 

}]; 

  * 事务 


- (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; 

return; 

} 

} 

}]; 

} 

参考

iOS学习笔记17-FMDB你好!

标签: 暂无
最后更新:2022年 11月 11日

陈昭

IT 程序员

打赏 点赞
< 上一篇
下一篇 >

文章评论

取消回复

COPYRIGHT © 2022 chenzhao. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang