http://blog.devtang.com/blog/2012/04/22/use-fmdb/
sqlite (http://www.sqlite.org/docs.html) 是一个轻量级的关系数据库。iOS SDK很早就支持了sqlite,在使用时,只需要加入 libsqlite3.dylib 依赖以及引入 sqlite3.h 头文件即可。但是,原生的sqlite API在使用上相当不友好,在使用时,非常不便。于是,开源社区中就出现了一系列将sqlite API进行封装的库,而FMDB (https://github.com/ccgus/fmdb) 则是开源社区中的优秀者。
FMDB在使用上相当方便。以下是一个简单的例子:
1234567891011 | Nsstring* docsdir = [NSSearchPathForDirectorIEsInDomains( NSdocumentDirectory, NSUserDomainMask, YES) lastObject]; Nsstring* dbpath = [docsdir stringByAppendingPathComponent:@"user.sqlite"]; FMDatabase* db = [FMDatabase databaseWithPath:dbpath]; [db open]; FMResultSet *rs = [db executequery:@"select * from people"]; while ([rs next]) { NSLog(@"%@ %@", [rs stringForColumn:@"firstname"], [rs stringForColumn:@"lastname"]); } [db close]; |
可以看到,使用FMDB后的数据库代码清晰明了,比原生的API优雅多了。另外,FMDB同时兼容ARC和非ARC工程,会自动根据工程配置来调整相关的内存管理代码。
使用说明该使用说明主要翻译自fmdb的github项目说明文档:https://github.com/ccgus/fmdb
引入相关文件首先将FMDB从github上clone下来,然后将以下文件copy到你的工程中:
12345678910 | FMDatabase.h FMDatabase.m FMDatabaseAdditions.h FMDatabaseAdditions.m FMDatabasePool.h FMDatabasePool.m FMDatabaseQueue.h FMDatabaseQueue.m FMResultSet.h FMResultSet.m |
建立数据库只需要如下一行即可,当该文件不存在时,fmdb会自己创建一个。如果你传入的参数是空串:@”” ,则fmdb会在临时文件目录下创建这个数据库,如果你传入的参数是 NulL,则它会建立一个在内存中的数据库。
1 | FMDatabase *db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"]; |
使用如下语句,如果打开失败,可能是权限不足或者资源不足。通常打开完 *** 作 *** 作后,需要调用close方法来关闭数据库。
12345678 | if (![db open]) { // error return; } // some operation // ... [db close]; |
除了Select *** 作之外,其它的都是更新 *** 作。更新 *** 作使用如下方法,如果有错误,可以用error参数中获得。
1 | -[FMDatabase executeUpdate:error:withArgumentsInArray:orVAList:] |
查询 *** 作示例如下。注意:即使 *** 作结果只有一行,也需要先调用FMResultSet的next方法。
123456789 | FMResultSet *s = [db executequery:@"SELECT * FROM mytable"]; while ([s next]) { //retrIEve values for each record } FMResultSet *s = [db executequery:@"SELECT COUNT(*) FROM mytable"]; if ([s next]) { int totalCount = [s intForColumnIndex:0]; } |
FMDB提供如下多个方法来获取不同类型的数据:
1234567891011 | intForColumn: longForColumn: longLongIntForColumn: boolForColumn: doubleForColumn: stringForColumn: dateForColumn: dataForColumn: datanocopyForColumn: UTF8StringForColumnIndex: objectForColumn: |
通常情况下,你并不需要关闭FMResultSet,因为相关的数据库关闭时,FMResultSet也会被自动关闭。
数据参数通常情况下,你可以按照标准的SQL语句,用?表示执行语句的参数,如:
1 | INSERT INTO mytable VALUES (?, ?, ?) |
然后,可以我们可以调用executeUpdate方法来将?所指代的具体参数传入,通常是用变长参数来传递进去的,如下:
12 | Nsstring *sql = @"insert into User (name,password) values (?,?)"; [db executeUpdate:sql, user.name, user.password]; |
这里需要注意的是,参数必须是NSObject的子类,所以象int,double,bool这种基本类型,需要封装成对应的包装类才行,如下所示:
1234 | // 错误,42不能作为参数 [db executeUpdate:@"INSERT INTO mytable VALUES (?)", 42]; // 正确,将42封装成 NSNumber 类 [db executeUpdate:@"INSERT INTO mytable VALUES (?)", [NSNumber numberWithInt:42]]; |
如果我们的app需要多线程 *** 作数据库,那么就需要使用FMDatabaseQueue来保证线程安全了。切记不能在多个线程中共同一个FMDatabase对象并且在多个线程中同时使用,这个类本身不是线程安全的,这样使用会造成数据混乱等问题。
使用FMDatabaseQueue很简单,首先用一个数据库文件地址来初使化FMDatabaseQueue,然后就可以将一个闭包(block)传入inDatabase方法中。在闭包中 *** 作数据库,而不直接参与FMDatabase的管理。
12345678910111213141516171819202122232425262728 | // 创建,最好放在一个单例的类中 FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath]; // 使用 [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]) { // … } }]; // 如果要支持事务 [queue inTransaction:^(FMDatabase *db, BOol *rollback) { [db executeUpdate:@"INSERT INTO mytable VALUES (?)", [NSNumber numberWithInt:3]]; if (whoopsSomethingWrongHappened) { *rollback = YES; return; } // etc… [db executeUpdate:@"INSERT INTO mytable VALUES (?)", [NSNumber numberWithInt:4]]; }]; |
为了查看sqlite中的数据,一个好的图形化界面的数据库管理程序是必不可少的。MysqL有phpmyadmin,那么sqlite呢?
我主要使用的是firefox的一个名为sqlite Manager的插件,安装此插件后,可以直接打开后缀名为sqlite的数据库文件。sqlite Manager提供一个图形化的界面来执行数据查询或更改 *** 作。如下图所示:
总结FMDB将sqlite API进行了很友好的封装,使用上非常方便,对于那些使用纯sqlite API来进行数据库 *** 作的app,可以考虑将其迁移到基于FMDB上,这对于以后数据库相关功能的开发维护,可以提高不少效率。
我在学习fmdb的时候做了一个小工程用于练习,我把它放到github上了。感兴趣的可以自行下载:https://github.com/tangqiaoboy/FmdbSample
祝大家玩得开心。
Posted by唐巧Apr 22nd,2012iOS
原创文章,版权声明:自由转载-非商用-非衍生-保持署名 |Creative Commons BY-NC-ND 3.0
自己测试程序
@H_517_1301@
#import <Foundation/Foundation.h>
#import "FMDatabase.h"
#import "FMDatabaseAdditions.h"
#import "FMDatabasePool.h"
#import "FMDatabaseQueue.h"
int main(int argc,const char * argv[])
{
@autoreleasepool {
// insert code here...
NSLog(@"Hello,World!");
NSfileManager *filemgr;
Nsstring *currentpath;
filemgr = [[NSfileManageralloc] init];
currentpath = [filemgrcurrentDirectoryPath];
//NSLog(@"%@",currentpath);
Nsstring *dbpath = [currentpath stringByAppendingPathComponent:@"I3DB.db3"];
FMDatabase *db = [FMDatabasedatabaseWithPath:dbpath];
if(db == NulL)
{
NSLog(@" Create DB Failed!");
}
[dbopen];
FMResultSet *rs = [dbexecutequery:@" select * from Tab_MHz where ID = 1"];
while ([rs next]) {
NSLog( @"%@",[rsstringForColumn:@"work"]);
}
[dbclose];
}
return 0;
}
注意数据放的位置在deBUG目录下 总结以上是内存溢出为你收集整理的【iOS功能实现】之:使用FMDB连接SQLite全部内容,希望文章能够帮你解决【iOS功能实现】之:使用FMDB连接SQLite所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)