iOS FMDB 數(shù)據(jù)庫(kù)(整理版)

寫(xiě)在前面的話:之前的那版因?yàn)榕虐娌缓每粗匦抡砹诉@份坎吻,所以這份跟之前的一樣啦~~~
————————————————

FMDB

1、簡(jiǎn)述:
1.1秩仆、FMDB是iOS平臺(tái)的SQLite數(shù)據(jù)庫(kù)框架混滔,是對(duì)libsqlite3框架的封裝
2.2、FMDB以O(shè)C的方式封裝了SQLite的C語(yǔ)言API
2鸠姨、FMDB的優(yōu)點(diǎn):
2.1、使用起來(lái)更加面向?qū)ο笱驼妫∪チ撕芏嗦闊┭惹ā⑷哂嗟腃語(yǔ)言代碼
2.2、對(duì)比蘋(píng)果自帶的Core Data框架核蘸,更加輕量級(jí)和靈活
2.3巍糯、提供了多線程安全的數(shù)據(jù)庫(kù)操作方法,有效地防止數(shù)據(jù)混亂
3值纱、FMDB的github地址 傳送門(mén)
4鳞贷、FMDB的三個(gè)核心類(lèi)

FMDatabase —— 一個(gè)FMDatabase對(duì)象就代表一個(gè)單獨(dú)的SQLite數(shù)據(jù)庫(kù) 用來(lái)執(zhí)行SQL語(yǔ)句
FMResultSet —— 使用FMDatabase執(zhí)行查詢后的結(jié)果集
FMDatabaseQueue —— 用于在多線程中執(zhí)行多個(gè)查詢或更新,它是線程安全的

5虐唠、基本使用
1.下載FMDB文件的GitHub搀愧,并將FMDB文件夾添加到項(xiàng)目中(也可使用CocoaPods導(dǎo)入)—— > pod'FMDB'
2.導(dǎo)入libsqlite3.0框架,導(dǎo)入頭文件FMDatabase.h
3.代碼實(shí)現(xiàn),與SQLite使用步驟相似咱筛,創(chuàng)建數(shù)據(jù)庫(kù)路徑搓幌,獲得數(shù)據(jù)庫(kù)路徑,打開(kāi)數(shù)據(jù)庫(kù)迅箩,然后對(duì)數(shù)據(jù)庫(kù)進(jìn)行增溉愁、刪、改饲趋、查操作拐揭,最后關(guān)閉數(shù)據(jù)庫(kù)。

導(dǎo)入libsqlite3.0庫(kù)

實(shí)例Demo

本例是一個(gè)學(xué)生的數(shù)據(jù)庫(kù)表格student奕塑,每個(gè)學(xué)生都自己所選的課程class堂污,具體信息如下圖Model:


Model

1、具體操作界面

具體操作界面

2龄砰、上代碼
2.1盟猖、創(chuàng)建 DataForFMDB.h 類(lèi),導(dǎo)入頭文件

#import"DataForFMDB.h"
#import <FMDB.h>

2.2换棚、創(chuàng)建FMDB單例式镐,以便全局共享

@interface DataForFMDB (){
FMDatabase *fmdb;
}
@end

@implementation DataForFMDB

static DataForFMDB *theData = nil;

+(instancetype)sharedDataBase{
    @synchronized(self) {
        if(!theData) {
            theData = [[DataForFMDB alloc] init];
            [theData initDataBase];
        }
     }
    return theData;
}

-(void)initDataBase{
    //獲得Documents目錄路徑
    NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    //文件路徑
    NSString *filePath = [documentPath stringByAppendingPathComponent:@"student.db"];
    //實(shí)例化FMDataBase對(duì)象
    NSLog(@"---path:%@",filePath);
    fmdb = [FMDatabase databaseWithPath:filePath];
    if([fmdb open]) {
        //初始化數(shù)據(jù)表
        [self addStudentTable];
        [self addClassTable];
        [fmdb close];
    }else{
        NSLog(@"數(shù)據(jù)庫(kù)打開(kāi)失敗---%@", fmdb.lastErrorMessage);
    } 
}

-(void)addStudentTable{
    NSString *studentSQL = @"create table if not exists student (id integerPrimary Key Autoincrement, sId integer, sName text, sAge integer)";
    BOOL studentSuccess = [fmdb executeUpdate:studentSQL];
    if(!studentSuccess) {
        NSLog(@"studentTable創(chuàng)建失敗---%@",fmdb.lastErrorMessage);
    } 
}

-(void)addClassTable{
    NSString *classSQL =@"create table if not exists class (id integerPrimary Key Autoincrement,scId integer, cName text)";
    BOOL classSuccess = [fmdb executeUpdate:classSQL];
    if(!classSuccess) {
        NSLog(@"classTable創(chuàng)建失敗---%@",fmdb.lastErrorMessage);
    }
 }

2.3、獲取student表全部?jī)?nèi)容

-(NSMutableArray*)getAllStudent{
    [fmdb open];
    NSMutableArray *array = [NSMutableArray new];
    FMResultSet *result = [fmdb executeQuery:@"select * from student"];
    while([resultnext]) {
        StudentFMDBModel *student = [[StudentFMDBModel alloc] init];
        student.sId = [[result stringForColumn:@"sId"] integerValue];
        student.sName = [result stringForColumn:@"sName"];
        student.sAge = [[result stringForColumn:@"sAge"] integerValue];
        [array addObject:student];
    }
    [fmdb close];
    return array;
}

//調(diào)用
self.dataArray = [[DataForFMDB sharedDataBase] getAllStudent];

2.4固蚤、student表添加內(nèi)容

-(void)addStudent:(StudentFMDBModel*)student{
    [fmdb open];
    NSString *SQL = @"insert into student(sId,sName,sAge) values(?,?,?)";
    BOOL isAddSuccess = [fmdb executeUpdate:SQL,@(student.sId),student.sName,@(student.sAge)];
    if(!isAddSuccess) {
        NSLog(@"studentTable插入信息失敗--%@",fmdb.lastErrorMessage);
    }
    [fmdb close];
}

//調(diào)用
[[DataForFMDB sharedDataBase] addStudent:student];

2.5娘汞、student表刪除內(nèi)容

-(void)deleteStudent:(StudentFMDBModel*)student{
    [fmdb open];
    NSString *SQL = @"delete from student where sId = ?";
    BOOL isDeleteSuccess = [fmdb executeUpdate:SQL,@(student.sId)];
    if(!isDeleteSuccess) {
        NSLog(@"studentTable刪除某一信息失敗--%@",fmdb.lastErrorMessage);
    }
    [fmdb close];
}

//調(diào)用
[[DataForFMDB sharedDataBase] deleteStudent:self.dataArray[indexPath.row]];

2.6、student表修改內(nèi)容

-(void)updateStudent:(StudentFMDBModel*)student{
    [fmdb open];
    NSString *SQL1 = @"update student set sName = ? where sId = ?";
    NSString *SQL2 = @"update student set sAge = ? where sId = ?";
    BOOL isSuccess1 = [fmdbexecuteUpdate: SQL1, student.sName,@(student.sId)];
    BOOL isSuccess2 = [fmdbexecuteUpdate: SQL2,@(student.sAge),@(student.sId)];
    if(!isSuccess1) {
        NSLog(@"student.sName修改失敗--%@",fmdb.lastErrorMessage);
    }
    if(!isSuccess2) {
        NSLog(@"student.sAge修改失敗--%@",fmdb.lastErrorMessage);
    }
    [fmdbclose];
}

//調(diào)用
[[DataForFMDB sharedDataBase] updateStudent:student];

2.7夕玩、刪除student表

-(void)deleteAllStudent{
    [fmdb open];
    NSString *SQL =@"delete from student";
    BOOL isSuccess = [fmdb executeUpdate:SQL];
    if(!isSuccess) {
        NSLog(@"studentTable全部刪除失敗--%@",fmdb.lastErrorMessage);
    }
    //student表刪除以后价说,對(duì)應(yīng)的class也要?jiǎng)h除
    [self deleteAllClass];
    [fmdb close];
}

//調(diào)用
[[DataForFMDB sharedDataBase] deleteAllStudent];

2.8、獲取某一student class表的全部課程

-(NSMutableArray*)getAllClassFromStudent:(StudentFMDBModel*)student{
    [fmdb open];
    NSMutableArray *array = [NSMutableArray new];
    FMResultSet *result = [fmdb executeQuery:[NSString stringWithFormat:@"select * from class where scId = %ld", student.sId]];
    while([result next]) {
        StudentClassModel*class = [[StudentClassModel alloc] init];
        class.cName= [result stringForColumn:@"cName"];
        [array addObject:class];
    }
    [fmdb close];
    return array;
}

//調(diào)用
self.dataArray = [[DataForFMDB sharedDataBase] getAllClassFromStudent: student];

2.9风秤、給class表添加課程

-(void)addClass:(StudentClassModel*)clas toStudent:(StudentFMDBModel*)student{
    [fmdb open];
    //scId integer, cName text
    NSString *SQL = [NSString stringWithFormat:@"insert into class (scId, cName) values (%ld,?)", student.sId];
    BOOL isSuccess = [fmdb executeUpdate:SQL, clas.cName];
    if(!isSuccess) {
        NSLog(@"classTable插入信息失敗--%@",fmdb.lastErrorMessage);
    }
    [fmdb close];
}

//調(diào)用
[[DataForFMDB sharedDataBase] addClass: class toStudent: student];

2.10、給class表刪除課程

-(void)deleteClass:(StudentClassModel*)clas toStudent:(StudentFMDBModel*)student{
    [fmdb open];
    NSString *SQL = [NSString stringWithFormat:@"delete from class where scId = %ld and cName = ?", student.sId];
    BOOL isSuccess = [fmdb executeUpdate:SQL,clas.cName];
    if(!isSuccess) {
        NSLog(@"classTable刪除某一信息失敗--%@",fmdb.lastErrorMessage);
    }
    [fmdb close];
}

//調(diào)用
[[DataForFMDB sharedDataBase] deleteClass: self.dataArray[indexPath.row] toStudent: student];

2.11扮叨、刪除student下某一的全部class

-(void)deleteAllCarsFromStudent:(StudentFMDBModel*)student{
    [fmdb open];
    NSString *SQL = [NSString stringWithFormat:@"delete from class where scId = %ld", student.sId];
    BOOL isSuccess = [fmdb executeUpdate:SQL];
    if(!isSuccess) {
        NSLog(@"student下某一的全部class刪除失敗--%@",fmdb.lastErrorMessage);
    }
    [fmdb close];
}

//調(diào)用
[[DataForFMDB sharedDataBase] deleteAllClassFromStudent: student];

2.12缤弦、刪除class表

-(void)deleteAllClass{
    NSString*SQL = @"delete from class";
    BOOL isSuccess = [fmdb executeUpdate:SQL];
    if(!isSuccess) {
        NSLog(@"classt全部刪除失敗--%@",fmdb.lastErrorMessage);
    } 
}

2.13、由名字查找學(xué)生student信息


查找操作界面
-(NSMutableArray*)seachAllInfoWith:(NSString*)str{
    [fmdb open];
    NSMutableArray *array = [NSMutableArray new];
    //通過(guò)名字查詢學(xué)生信息
    NSString *SQL = [NSString stringWithFormat:@"select * from student where sName = '%@' ", str]; // '%@' 可以查詢中文
    FMResultSet *result = [fmdb executeQuery:SQL];
    while([resultnext]) {
        StudentFMDBModel *student = [[StudentFMDBModel alloc] init];
        student.sId= [result intForColumn:@"sId"];
        student.sName= [result stringForColumn:@"sName"];
        [array addObject:student];
    }
    [fmdb close];
    return array;
}

//調(diào)用
self.dataArray = [[DataForFMDB sharedDataBase] seachAllInfoWith: textField.text];

2.14彻磁、全部信息


全部信息界面

數(shù)據(jù)代碼:

@property(nonatomic,strong)NSMutableArray*studentArray;//student數(shù)據(jù)源數(shù)組
@property(nonatomic,strong)NSMutableArray*allInfoArray;//student對(duì)應(yīng)class數(shù)據(jù)源數(shù)組

self.studentArray = [[DataForFMDB sharedDataBase] getAllStudent];
for(inti =0; i<self.studentArray.count; i++){
    StudentFMDBModel *student =self.studentArray[i];
    NSMutableArray *array = [[DataForFMDB sharedDataBase] getAllClassFromStudent:student];
    [self.allInfoArray addObject:array];
}

知識(shí)點(diǎn)總結(jié)

1碍沐、數(shù)據(jù)庫(kù)插入命令SQL insert into
1.1、executeUpdate:不確定的參數(shù)用衷蜓?來(lái)占位(后面參數(shù)必須是oc對(duì)象累提,“;”代表語(yǔ)句結(jié)束)

[fmdb executeUpdate:@"insert into student(sId,sName,sAge) values(?,?,?);" ,@(student.sId), student.sName, @(student.sAge)];  
//int/integer 類(lèi)型的要加 “@(xxx)”轉(zhuǎn)成NSNumber類(lèi)型的

1.2磁浇、executeUpdateWithForamat:不確定的參數(shù)用%@斋陪,%d等來(lái)占位 (參數(shù)為原始數(shù)據(jù)類(lèi)型,執(zhí)行語(yǔ)句不區(qū)分大小寫(xiě)

 [fmdb executeUpdateWithForamat:@"insert intot student (sId,sName,sAge)values(%ld,%@,%ld);",student.sId, student.sName, student.sAge]; 

1.3无虚、參數(shù)是數(shù)組的使用方式

[fmdb executeUpdate:@"insert into student (sId,sName,sAge) values(?,?,?);" withArgumentsInArray:@[@(student.sId), student.sName, @(student.sAge)]];

2缔赠、數(shù)據(jù)庫(kù)刪除命令SQL delete

2.1、不確定的參數(shù)用友题?來(lái)占位 (后面參數(shù)必須是oc對(duì)象,需要將int包裝成OC對(duì)象)
[fmdb executeUpdate:@"delete from student where sId = ?;", @(student.sId)];
2.2嗤堰、不確定的參數(shù)用%@,%d等來(lái)占位
[fmdb executeUpdateWithFormat:@"delete from student where name = %@;",student.sName];

3度宦、數(shù)據(jù)庫(kù)修改命令SQL update

修改學(xué)生的名字 
[fmdb executeUpdate:@"update student set sName = ? where sId = ?",student.sName,@(student.sId)];

4踢匣、數(shù)據(jù)庫(kù)查詢命令SQL select ... from

//select命令就是查詢,執(zhí)行查詢的方法是以-excuteQuery開(kāi)頭的戈抄。
//執(zhí)行查詢時(shí)离唬,如果成功返回FMResultSet對(duì)象,錯(cuò)誤返回nil呛凶。
//與執(zhí)行更新相當(dāng)男娄,支持使用NSError參數(shù)。
//同時(shí)漾稀,你也可以使用-lastErrorCode和-lastErrorMessage獲知錯(cuò)誤信息模闲。
FMResultSet獲取不同數(shù)據(jù)格式的方法:
intForColumn:
longForColumn:
longLongIntForColumn:
boolForColumn:
doubleForColumn:
stringForColumn:
dataForColumn:
dataNoCopyForColumn:
UTF8StringForColumnIndex:
objectForColumn:

5、據(jù)庫(kù)銷(xiāo)毀命令SQL ** drop ...**

//如果表格存在 則銷(xiāo)毀 
[fmdb executeUpadate:@"drop table if existst student;"];

6崭捍、使用FMDatabaseQueue類(lèi)實(shí)現(xiàn)多線程操作
在多個(gè)線程中同時(shí)使用一個(gè)FMDatabase實(shí)例是不明智的∈郏現(xiàn)在你可以為每 個(gè)線程創(chuàng)建一個(gè)FMDatabase對(duì)象,不要讓多個(gè)線程分享同一個(gè)實(shí)例殷蛇,他無(wú)法在多個(gè)線程中同事使用实夹。否則程序會(huì)時(shí)不時(shí)崩潰或者報(bào)告異常。所以粒梦,不要初始化FMDatabase對(duì)象亮航,然后在多個(gè)線程中使用。這時(shí)候匀们,我們就需要使 用FMDatabaseQueue來(lái)創(chuàng)建隊(duì)列執(zhí)行事務(wù)缴淋。

//1.創(chuàng)建隊(duì)列
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
__block BOOL whoopsSomethingWrongHappened =true;
//2.把任務(wù)包裝到事務(wù)里
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
    whoopsSomethingWrongHappened &= [db executeUpdate:@"insert into
myTable values (?)", [NSNumber numberWith:1]];
    whoopsSomethingWrongHappened &= [db executeUpdata:@"insert into myTable values (?)", [NSNumber numberWithInt:2]];
    whoopsSomethingWrongHappened &= [db executeUpdata:@“insert into myTable values(?)”[NSNumber  numberWithInt:3]];
    //如果有錯(cuò)誤 返回
    if(!whoopsSomethingWrongHappened)  {
        *rollback = YES;
        return;
      }
}];

——————————————————
有什么問(wèn)題歡迎大家提問(wèn)喲,O(∩_∩)O~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末泄朴,一起剝皮案震驚了整個(gè)濱河市重抖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌祖灰,老刑警劉巖钟沛,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異局扶,居然都是意外死亡恨统,警方通過(guò)查閱死者的電腦和手機(jī)叁扫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)延欠,“玉大人陌兑,你說(shuō)我怎么就攤上這事∮缮樱” “怎么了兔综?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)狞玛。 經(jīng)常有香客問(wèn)我软驰,道長(zhǎng),這世上最難降的妖魔是什么心肪? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任锭亏,我火速辦了婚禮,結(jié)果婚禮上硬鞍,老公的妹妹穿的比我還像新娘慧瘤。我一直安慰自己,他們只是感情好固该,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布锅减。 她就那樣靜靜地躺著,像睡著了一般伐坏。 火紅的嫁衣襯著肌膚如雪怔匣。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,679評(píng)論 1 305
  • 那天桦沉,我揣著相機(jī)與錄音每瞒,去河邊找鬼。 笑死纯露,一個(gè)胖子當(dāng)著我的面吹牛剿骨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播埠褪,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼懦砂,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了组橄?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤罚随,失蹤者是張志新(化名)和其女友劉穎玉工,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體淘菩,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡遵班,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年屠升,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狭郑。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡腹暖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出翰萨,到底是詐尸還是另有隱情脏答,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布亩鬼,位于F島的核電站殖告,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏雳锋。R本人自食惡果不足惜黄绩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望玷过。 院中可真熱鬧爽丹,春花似錦、人聲如沸辛蚊。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)嚼隘。三九已至诽里,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間飞蛹,已是汗流浹背谤狡。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留卧檐,地道東北人墓懂。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像霉囚,于是被迫代替她去往敵國(guó)和親捕仔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容