FMDB
前言.
去年整理的文章了,好久不做ios,再不发,估计ios就废了,拿来记录一下,大牛勿喷
一、FMDB简介
1.什么是 FMDB
FMDB 是 iOS 平台的 SQLite 数据库框架
FMDB 以 OC 的方式封装了 SQLite 的 C 语言 API
2.FMDB的优点
使用起来更加面向对象,省去了很多麻烦、冗余的C语言代码
对比苹果自带的Core Data框架,更加轻量级和灵活
提供了多线程安全的数据库操作方法,有效地防止数据混乱
3.FMDB 的 github 地址
二、使用说明
cocopads 引入 FMDB 库
pod 'FMDB'
三、核心类
FMDB有三个主要的类
(1)FMDatabase
一个FMDatabase对象就代表一个单独的SQLite数据库
用来执行SQL语句
(2)FMResultSet
使用FMDatabase执行查询后的结果集
(3)FMDatabaseQueue
用于在多线程中执行多个查询或更新,它是线程安全的
四、打开数据库
通过指定SQLite数据库文件路径来创建FMDatabase对象
// 1..创建数据库对象
FMDatabase *db = [FMDatabase databaseWithPath:path];
// 2.打开数据库
if ([db open]) {
// do something
} else {
DLog(@"fail to open database");
}
文件路径有三种情况
(1)具体文件路径
如果不存在会自动创建
[备注]使用绝对路径
(2)空字符串@””
会在临时目录创建一个空的数据库
当FMDatabase连接关闭时,数据库文件也被删除
(3)nil
会创建一个内存中临时数据库,当FMDatabase连接关闭时,数据库会被销毁
【备注】path 可以是相对路径,也可以是绝对路径。
四、数据库操作
1.执行更新操作
在FMDB中,除查询以外的所有操作,都称为“更新”
create、drop、insert、update、delete等
使用executeUpdate:方法执行更新
1)(BOOL)executeUpdate:(NSString*)sql, …
** 示例 CREATE (建表操作)
NSString *createTableSqlString = @"CREATE TABLE IF NOT EXISTS t_student (id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL, age integer NOT NULL)";
[db executeUpdate:createTableSqlString];
** 示例INSERT(写入数据)
//不确定的参数用?来占位
NSString *sql = @"insert into t_student (name, age) values (?, ?)";
[db executeUpdate:sql, @"zhangsan", [NSNumber numberWithInt:18]];
** 示例DELETE(删除数据)
NSString *sql = @"delete from t_student where id = ?";
[db executeUpdate:sql, [NSNumber numberWithInt:1]];
** 示例UPDATE(更改数据)
NSString *sql = @"update t_student set name = "heiheihei" where id = ?";
[db executeUpdate:sql, [NSNumber numberWithInt:1]];
2)(BOOL)executeUpdateWithFormat:(NSString*)format, …
示例:
//不确定的参数用%@,%d等来占位
NSString *sql = @"insert into t_student (name,age) values (%@,%i)";
[db executeUpdateWithFormat:sql, @"zhangsan", 18];
3)(BOOL)executeUpdate:(NSString*)sql withParameterDictionary:(NSDictionary *)
示例:
NSDictionary *studentDict = [NSDictionary dictionaryWithObjectsAndKeys:@"lisi", @"name", @"18", @"age", nil];
[db executeUpdate:@"insert into t_student (name, age) values (:name, :age)" withParameterDictionary:studentDict];
…
2、执行查询操作
查询方法
1)(FMResultSet )executeQuery:(NSString)sql, …
2)(FMResultSet )executeQueryWithFormat:(NSString)format, …
…
示例:
// 4.查询
NSString *sql = @"select id, name, age FROM t_student";
FMResultSet *rs = [db executeQuery:sql];
while ([rs next]) {
int id = [rs intForColumnIndex:0];
NSString *name = [rs stringForColumnIndex:1];
int age = [rs intForColumnIndex:2];
NSDictionary *studentDict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:id], @"id", name, @"name", [NSNumber numberWithInt:age], @"age", nil];
[studentArray addObject:studentDict];
}
3、多语句和批处理
FMDatabase 可以通过 -executeStatements:withResultBlock: 方法在一个字符串中执行多语句。
NSString *sql = @"CREATE TABLE IF NOT EXISTS bulktest1 (id integer PRIMARY KEY AUTOINCREMENT, x text);"
"CREATE TABLE IF NOT EXISTS bulktest2 (id integer PRIMARY KEY AUTOINCREMENT, y text);"
"CREATE table IF NOT EXISTS bulktest3 (id integer primary key autoincrement, z text);"
"insert into bulktest1 (x) values ('XXX');"
"insert into bulktest2 (y) values ('YYY');"
"insert into bulktest3 (z) values ('ZZZ');"
;
result = [db executeStatements:sql];
sql = @"select count(*) as count from bulktest1;"
"select count(*) as count from bulktest2;"
"select count(*) as count from bulktest3;";
result = [db executeStatements:sql withResultBlock:^int(NSDictionary *resultsDictionary) {
NSLog(@"dictionary=%@", resultsDictionary);
return 0;
}];
五、队列和线程安全
在多线程中同时使用 FMDatabase 单例是极其错误的想法,会导致每个线程创建一个 FMDatabase 对象。不要跨线程使用单例,也不要同时跨多线程,不然会奔溃或者异常。
因此不要实例化一个 FMDatabase 单例来跨线程使用。
相反,使用 FMDatabaseQueue,下面就是它的使用方法:
1、创建队列
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
2.示例:
[queue inDatabase:^(FMDatabase *db) {
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];
FMResultSet *rs = [db executeQuery:@"select * from foo"];
while ([rs next]) {
...
}
}];
3.把操作放在事务中也很简单,示例:
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];
if (whoopsSomethingWrongHappened) {
*rollback = YES;
return;
}
// ...
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]];
}];
fmdb使用遇到的问题及解决
[参考文档]
http://blog.devtang.com/2012/04/22/use-fmdb/
http://www.hcios.com/archives/921