FMDB的简单使用
1.FMDB是什么?
iOS中的原生SQLite API在使用中相当繁琐。于是,相应的对SQLite API进行封装的第三类库就应运而生,例如:FMDB,PlausibleDatabase等。FMDB是其中一款简单、易用的类库。
FMDB的安装推荐使用CocoaPods,不熟悉CocoaPods的可以看看(http://www.jianshu.com/p/c29db1c6713d) 中关于CocoaPods的安装及使用。
2.FMDB中的常用类
FMDatabase:更新数据库使用这个类。
FMResultSet:在数据库中执行查询操作中使用这个类。
FMDatabaseQueue:在多线程中使用查询和更新操作,需使用这个类。
3.创建数据库:
3.1对FMDatabase类实例化
daPath为数据库路径
NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *dbPath = [documentPath stringByAppendingPathComponent:@"db.sqlite"];
FMDatabase *db = [FMDatabase databaseWithPath:dbPath];
3.2打开数据库
这里使用的是FMDatabase类中的对象方法:
如果数据库已经存在,则打开数据库,否则创建数据库
[db open];
3.3关闭数据库
同样使用的是FMDatabase类中的对象方法:
[db close];
4.数据库的操作
4.1更新数据库
在FMDB中,创建表、增、删、改等都视为对数据库的更新操作,由FMDatabase类中的对象方法执行:
- (BOOL)executeUpdate:(NSString*)sql, ...;
这个方法执行一个SQL语句(任何不需要返回数据的SQL语句,例如:插入、更改、删除)。
这个方法内利用sqlite3_prepare_v2
sqlite3_bind
sqlite_step
来进行更新。
4.1.1创建表(create table)
创建SQL语句, 使用更新数据库方法:
if ([db open]) {
NSString *createTableSql = @"create table 'personInfo' (sid integer primary key autoincrement not null,name text,gender text,age integer,image blob);";
BOOL reslut = [db executeUpdate:createTableSql];
if (reslut == YES) {
NSLog(@"表创建成功");
}
}
4.1.2插入(insert)
创建SQL语句, 使用更新数据库方法:
NSString *insertSql2 = @"insert into 'personInfo'(name,gender,age,image) values('zhangsan','m',?,?);";
for (NSInteger i = 0; i < 5; i++) {
BOOL result = [db executeUpdate:insertSql2,[NSNumber numberWithInteger:20+i], data];
if (result == YES) {
NSLog(@"插入成功");
}
}
当插入中有NSData类型的数据,也就是blob,在SQL语句中用?
占位,@"Gus"
即为需要插入的NSData。
当SQL语句中有多个?
时,按?
顺序依次添加@"Gus"
[db executeUpdate:@"INSERT INTO test (name) VALUES (?)", @"Gus"];
4.1.3删除(delete)
创建SQL语句, 使用更新数据库方法:
NSString *deleteSql = @"delete from 'personInfo' where age = 20;";
BOOL result = [db executeUpdate:deleteSql];
if (result == YES) {
NSLog(@"删除成功");
}
4.1.4更改(update)
创建SQL语句, 使用更新数据库方法:
NSString *updateSql = @"update 'personInfo' set name = 'lisi' where age = 21;";
BOOL update = [db executeUpdate:updateSql];
if (update == YES) {
NSLog(@"更改成功");
}
4.2查找(select)
注意:查找操作有返回值,不再使用更新数据库方法,需要的方法依旧为属于FMDatabase类的对象方法
- (FMResultSet *)executeQuery:(NSString*)sql, ...;
方法返回值为FMResultSet *.
NSString *selectSql = @"select *from 'personInfo' where name = 'lisi';";
FMResultSet *fr = [db executeQuery:selectSql];
while ([fr next]) {
NSString *name = [fr stringForColumnIndex:1];
NSString *gender = [fr stringForColumnIndex:2];
NSInteger age = (NSInteger)[fr intForColumnIndex:3];
NSLog(@"name = %@,gender = %@, age = %ld",name,gender,age);
}
[fr close];
[fr next]
搜索返回集的下一行,搜索成功返回YES
类似SQLITE_ROW
,到达最后一行返回NO
类似SQLITE_DONE
。
[fr close]
关闭搜索集
5.多线程编程
在FMDatabase.m中,我们可以看到- (BOOL)open;
的实现中并没有添加同步锁,这样当一个应用中使用了多线程操作数据库,会引起数据库混乱。这时,我们需要使用FMDatabaseQueue来保证数据库的使用(这样解释,逻辑可能有点不对)。
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:@""];
dispatch_queue_t currentQueue = dispatch_queue_create("q1", DISPATCH_QUEUE_CONCURRENT);
for (NSInteger i = 0; i < 10; i++) {
dispatch_async(currentQueue, ^{
[queue inDatabase:^(FMDatabase *db) {
BOOL result = [db executeUpdate:insertSql,data];
if (result == YES) {
NSLog(@"添加成功");
}else
{
NSLog(@"添加失败");
}
}];
});
}