fmdb在项目中的使用

    对于新手来说,iOS中使用的数据库框架,fmdb无疑是较为简单方便的。在我接触fmdb前,查阅了很多资料,发现网上的demo参差不齐,有些过于基础,项目中使用需要进一步封装。因此,我针对项目中的时候,参考别人的demo,自己改进并写了个封装。希望对大家使用fmdb有帮助。如果有错误的地方,希望多多指正,谢谢。此篇文章紧对刚学习fmdb的新人提供参考,大神请忽略。iOS开发群143898492,欢迎有兴趣的加入。

FMDB封装的工具

这是封装的工具类JHFMDBManager.h文件

#import <Foundation/Foundation.h>

#import"FMDB.h"

typedefvoid(^JHDBBlock)(FMDatabase*jh_db);

@interfaceJHFMDBManager :NSObject

+(instancetype)sharedInstance;

/**

*数据库操作

*

*@param block操作block回调

*/

- (void)SQLHandler:(JHDBBlock)block;

@end

这是JHFMDBManager.m文件,FMDatabaseQueue是多线程安全的,这个使用时需要注意,多线程操作数据时,必须保证FMDatabaseQueue是同一个对象,否则会导致数据正在被操作时被锁住的情况,导致操作失败。这里用了懒加载,只new一个对象。(由于排版的原因导致下面的代码分割开了,下面的代码应是连在一块的)。一般项目中只生成一个数据库,数据库里面多张表,保存不同对象数据。这里封装的- (void)SQLHandler:(JHDBBlock)block方法,是调用sql语句的block。如何使用请看下文。

#import"JHFMDBManager.h"

@interfaceJHFMDBManager()

@property(nonatomic,strong)FMDatabaseQueue* queue;

@end

@implementationJHFMDBManager

+ (instancetype)sharedInstance

{

static JHFMDBManager*sharedInstance =nil;

static dispatch_once_tonceToken;

dispatch_once(&onceToken, ^{

sharedInstance = [selfnew];

});

returnsharedInstance;

}

//获取路径

+ (NSString*)dbPathWithDirectoryName:(NSString*)directoryName DataBaseName:(NSString*)dbname

{

NSString*docsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)lastObject];

NSFileManager*filemanage = [NSFileManagerdefaultManager];

if(directoryName ==nil|| directoryName.length==0) {

docsPath = [docsPath stringByAppendingPathComponent:@"jhOnesmile"];

}else{

docsPath = [docsPath stringByAppendingPathComponent:directoryName];

}

BOOLisDir;

BOOLexit =[filemanage fileExistsAtPath:docsPathisDirectory:&isDir];

if(!exit || !isDir) {

[filemanage createDirectoryAtPath:docsPathwithIntermediateDirectories:YESattributes:nilerror:nil];

}

NSString*dbpath = [docsPathstringByAppendingPathComponent:dbname];

NSLog(@"---------%@", dbpath);

returndbpath;

}

- (void)SQLHandler:(JHDBBlock)block

{

//线程安全,可以用多线程操作

[self.queue inDatabase:^(FMDatabase*db) {

if([db open]) {

@try{

//成功回调

block(db);

}

@catch(NSException *exception) {

//处理异常,也可以直接抛出,这样调用者就能捕获到异常信息

NSLog(@"处理异常,异常信息: %@", exception);

}

@finally{

[dbclose];//如果[db open]就要保证能关闭

}

}else{

NSLog(@"数据库打开失败,错误提示:%@", [db lastError]);

}

db =nil;

}];

}

/**

*创建数据库多线程管理工具,必须是一个对象,否则会导致多线程使用中,出现操作失败的现象

*(两个操作同时操作一个数据库会出现程序锁,导致操作失败)

*

*@return

*/

-(FMDatabaseQueue*)queue{

if(_queue==nil) {

//只创建一个数据库,文件夹叫onesmile,数据库文件名字onesmile.sqlite,表名称根据创建的表来确定

NSString*dbName =@"onesmile.sqlite";

NSString*fileName =@"onesmile";

NSString*dbPath = [[self class]dbPathWithDirectoryName:fileNameDataBaseName:dbName];

_queue= [FMDatabaseQueue databaseQueueWithPath:dbPath];

}

return_queue;

}

自定义FMDB工具类的使用

我们有一个学生类,类属性如下。那么我们该如何将这个类的对象保存到数据库中呢?对于很多新手来说,希望省事点,能直接将对象保存到数据库,然而这是无法做到的。比如某个班级,有60个学生,我们应先建立一个学生表,表里面的列便是学生类的属性(正如项目中需要保存很多条新闻数据,或者是聊天数据等,那么新闻是一个模型,很多条新闻便是很多个对象,模型的属性我们便可以保存为新闻表的列)(这里有点啰嗦,只是解释给新手看的,高手略过)。

@interfaceJHUserModel :NSObject

/**用户名*/

@property(nonatomic,copy)NSString*name;

/**用户地*/

@property(nonatomic,copy)NSString*address;

/**用户年龄*/

@property(nonatomic,copy)NSString*age;

@end

1.创建学生类表

我们在需要保存数据的控制器里,先创建该学生类student的表。createSqlStr是保存sql语句,这里的sql语句的意思很明显,如果没有student这个表,则创建,并且列为id,name,address,age,id是主键,其他列都保存为text类型,且不为空(如果可以为空对应的列则not null去掉即可)。关于更深层次的sql语句的学习,推荐去w3c官网学习,毕竟不会sql语句,用起fmdb会感到很吃力。创建代码如下:

//创建表

[[JHFMDBManager sharedInstance]SQLHandler:^(FMDatabase*jh_db) {

NSString*createSqlStr =@"create table if not exists student (id integer primary key, name text not null,address text not null,age text not null)";

BOOL res = [jh_db executeUpdate:createSqlStr];

if(!res) {

NSLog(@"创建表出错");

}else{

NSLog(@"创建表成功");

}

}];

2.查询表

这里的set是查询返回的FMResultSet对象,使用while循环遍历所有查询到的结果,在遍历内获取你想要的列即可。实际应用中,有可能需要排序,翻页查询,某个列的查询最大最小值的那条数据等等,这就涉及到sql语句的应用了,具体可查询相关资料,只要写出该sql语句即可用如下的方式运行

//查询数据

[[JHFMDBManager sharedInstance]SQLHandler:^(FMDatabase*jh_db) {

NSString*sqlString =@"select *from student";

FMResultSet*set = [jh_db executeQuery:sqlString];

while([set next]) {

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

NSString*address = [set stringForColumn:@"address"];

NSString*age = [set stringForColumn:@"age"];

NSLog(@"用户姓名:%@,地址:%@,年龄:%@",name,address,age);

}

}];

3.插入数据

//插入数据

[[JHFMDBManager sharedInstance] SQLHandler:^(FMDatabase *jh_db) {

NSString *sqlString =@"insert into student (name,address,age) values(?,?,?)";

BOOL res = [jh_db executeUpdate:sqlString,student.name,student.address,[NSString stringWithFormat:@"%d",16]];

if(!res) {

NSLog(@"插入出错");

}else{

NSLog(@"插入成功");

}

}];

4.更新数据

某条数据变动了,则使用更新方法。

//更新数据

[[JHFMDBManager sharedInstance] SQLHandler:^(FMDatabase *jh_db) {

NSString *sqlString =@"update student set address = ? where age = ?";

BOOLres = [jh_db executeUpdate:sqlString,@"gfds",student.age];

if(!res) {

NSLog(@"更新出错");

}else{

NSLog(@"更新成功");

}

}];

5.删除数据

删除数据需谨慎使用,一定要添加条件进行删除,否则容易闹出将整表甚至整个数据库删除的乌龙,需谨慎使用!

//删除数据

[[JHFMDBManager sharedInstance] SQLHandler:^(FMDatabase *jh_db) {

NSString *sqlString =@"delete from userModel where name = ?";

BOOLres = [jh_db executeUpdate:sqlString,userModel.name];

if(!res) {

NSLog(@"删除出错");

}else{

NSLog(@"删除成功");

}

}];

以上所有的操作都可以在子线程中执行,因为使用了FMDatabaseQueue,所以是线程安全的。很多不会用数据库的新人,都是对sql语句不熟悉导致的。因此建议使用fmdb的时候,电脑装个数据库查看软件,可以查看你对数据库进行的操作,否则你进行了数据操作,根本不知道数据库在背后到底如何做了什么。新人推荐使用SQLite Professional,想更深去学习sql,可以装个mysql环境,Mysql是免费的,可以使用它自带的MYSQLWorkbench管理工具查看数据库的操作。对于大神来说略过。

我是iOS菜鸟onesmile 一笑,刚开始写简书,希望各位多多指教。欢迎到iOS开发群143898492交流,群较小,但探讨问题较活跃。只要有问题都可以在里面,提问。懂的都会尽力解答。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容