FMDB是建立在SQLite之上的,以Objective-C的方式封装了SQLite的C语言API。
在FMDB中主要有三个类:
创建FMDatabase对象时参数为SQLite数据库文件路径。该路径可以是以下三种之一:
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *dbPath = [docsPath stringByAppendingPathComponent:@"test.db"];
FMDatabase *db = [FMDatabase databaseWithPath:dbPath];
空字符串(@””)。表示会在临时目录创建一个空的数据库,当FMDatabase 链接关闭时,文件也被删除。
NULL. 将创建一个内在数据库。同样的,当FMDatabase连接关闭时,数据会被销毁。
在和数据库交互之前,需要打开数据库。
if (![db open]) {
NSLog(@"数据库打开失败!");
return;
}
一切不是SELECT命令的命令都视为更新。常用的更新操作包括: CREATE、UPDATE、INSERT、ALTER、DELETE、DROP、REPLACE 等。执行更新返回一个BOOL值。YES表示执行成功,否则表示出错。可以调用 -lastErrorMessage 和 -lastErrorCode方法来得到更多信息。
[db executeUpdate:@"create table t_user (userId text, name text,age integer)"];
NSString *sql = [NSString stringWithFormat:@"insert or replace into t_user (userId,name,age) values ('%@','%@','%@');",@"111", @"张三",[NSNumber numberWithInt:20]];
BOOL flag = [db executeUpdate:sql];
if (flag) {
NSLog(@"执行数据插入成功!");
}
执行查询的方法是以 - excuteQuery开头的。执行查询时,如果成功返回FMResultSet对象, 错误返回nil. 也可以使用 -lastErrorCode和-lastErrorMessage获知错误信息。FMResultSet对象是一个结果集,可以使用next方法移动到下一条记录。
//- (BOOL)executeUpdate:(NSString*)sql, ...
//- (BOOL)executeUpdateWithFormat:(NSString*)format, ...
//- (BOOL)executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments
//
FMResultSet *rs = [db executeQuery:@"SELECT * FROM t_user"];
while ([rs next]) {
NSString *name = [rs stringForColumn:@"Name"];
int age = [rs intForColumn:@"Age"];
NSLog(@"name:%@,Age:%d",name,age);
}
执行结果:
FMResultSet 提供了很多方法来获得合适的格式值:
intForColumn:
longForColumn:
longLongIntForColumn:
boolForColumn:
doubleForColumn:
stringForColumn:
dataForColumn:
dataNoCopyForColumn:
UTF8StringForColumnIndex:
objectForColumn:
无需调用 [FMResultSet close]来关闭结果集, 当新的结果集产生,或者其数据库关闭时,会自动关闭。
关闭数据库连接,释放资源。
[db close];
多个线程同时使用一个FMDatabase实例容易出现数据的错乱,因为这个类不是线程安全的。这时可以使用FMDatabaseQueue来多线程异步执行多次数据操作。
//创建队列
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:dbPath];
[queue inDatabase:^(FMDatabase *db) {
[db executeUpdate:@"insert into t_user (userId, name, age) values (?,?,?)", @"113", @"王五",[NSNumber numberWithInt:23]];
//
[db executeUpdate:@"insert into t_user (userId, name, age) values (?,?,?)", @"114", @"赵六",[NSNumber numberWithInt:24]];
FMResultSet *rs = [db executeQuery:@"select * from t_user"];
while([rs next]) {
NSString *userId = [rs stringForColumn:@"userId"];
NSString *name = [rs stringForColumn:@"Name"];
int age = [rs intForColumn:@"Age"];
NSLog(@"userId:%@,name:%@:age:%d",userId,name,age);
}
}];
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
NSString *sql1 = [NSString stringWithFormat:@"delete from t_user where userId = '%@' and name = '%@'", @"111",@"张三"];
NSString *sql2 = [NSString stringWithFormat:@"delete from t_user where userId = %@' and name = '%@'", @"112",@"李四"];
BOOL flagError1 = [db executeUpdate:sql1];
BOOL flagError2 = [db executeUpdate:sql2];
if (!flagError1 || !flagError2) {
*rollback = YES; //回滚操作
}
}];
执行结果:
可以看到只有一条数据库语句有问题。第一条数据库已经执行完成,但是当执行第二条数据库的时候发现出错了,所以执行回滚操作,这样数据库中的结果还是有“张三”这个用户。
参考资料:
https://github.com/ccgus/fmdb
http://my.oschina.net/u/2346786/blog/515540
http://blog.csdn.net/xyz_lmn/article/details/9312837