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交流,群較小,但探討問題較活躍。只要有問題都可以在里面,提問。懂的都會盡力解答。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容