前言
以前使用SQLite十分的麻煩,代碼很冗余,所以開(kāi)發(fā)者朋友們一般在實(shí)際開(kāi)發(fā)的過(guò)程中都是使用的是FMDB這個(gè)開(kāi)元框架,那么下面我們就來(lái)了解一下FMDB這個(gè)輕量級(jí)的框架的簡(jiǎn)單使用吧.
- 基本概念:
所謂的FMDB就是iOS平臺(tái)的SQLite數(shù)據(jù)庫(kù)框架.是以O(shè)C的方式封裝了SQLite的C語(yǔ)言API.
- 使用FMDB的優(yōu)點(diǎn):
2.1, 使用FMDB比使用SQLite更加面向?qū)ο?省去了很多麻煩的操作,減少了冗余的C語(yǔ)言代碼.
2.2, 提供了多線程安全的數(shù)據(jù)庫(kù)操作方法, 有效的防止了對(duì)個(gè)對(duì)象同時(shí)訪問(wèn)該數(shù)據(jù)庫(kù)造成的數(shù)據(jù)紊亂等現(xiàn)象.
- 使用FMDB的注意點(diǎn):
手動(dòng)加載FMDB: 需要將source中的fmdb拖入項(xiàng)目,并且添加"libsqlite3.0.tbd"靜態(tài)庫(kù),需要在PCH文件中引入頭文件
- FMDB的基本結(jié)構(gòu)
重點(diǎn): FMDB的三個(gè)核心類(lèi)
3.1, FMDatabase: 一個(gè)FMDatabase對(duì)象就代表一個(gè)SQLite數(shù)據(jù)庫(kù)。用于執(zhí)行SQL語(yǔ)句。
3.2, FMResultSet: 使用FMDatabase執(zhí)行查詢后的結(jié)果集
3.3, FMDatabaseQueue: 用于多線程中執(zhí)行更新與查詢, 它是現(xiàn)成安全的
- 如何打開(kāi)數(shù)據(jù)庫(kù)以及注意點(diǎn):
打開(kāi)數(shù)據(jù)庫(kù): 是通過(guò)指定的SQLite數(shù)據(jù)庫(kù)文件路徑來(lái)創(chuàng)建FMDatabase對(duì)象的.
// 打開(kāi)數(shù)據(jù)庫(kù)
FMDatabase *db = [FMDatabase databaseWithPath:filePath];
if (![db open]) {
NSLog(@"打開(kāi)數(shù)據(jù)庫(kù)失敗, 直接返回");
return;
}
注意點(diǎn): 文件路徑可能有以下三種情況:
5.1, 具體的文件路徑: 意思就是如果該路徑不存在, 系統(tǒng)會(huì)自動(dòng)創(chuàng)建路徑.
5.2, 空字符串@"" : 會(huì)在臨時(shí)的目錄下創(chuàng)建一個(gè)空的數(shù)據(jù)庫(kù), 只有當(dāng)FMDatabase連接關(guān)閉時(shí), 數(shù)據(jù)庫(kù)文件也會(huì)被刪除.
5.3, nil : 會(huì)在內(nèi)存中創(chuàng)建一個(gè)臨時(shí)的數(shù)據(jù)庫(kù), 當(dāng)FMDatabase連接關(guān)閉時(shí),數(shù)據(jù)庫(kù)文件也會(huì)被刪除掉.
- 執(zhí)行更新操作
6, 執(zhí)行更新: 在FMDB中,除了查詢,所有的操作都得update操作,使用executeUpdate:方法執(zhí)行更新操作
[db executeUpdate:@"UPDATE t_student SET age = ? WHERE name = ?;", @20, @"Alex"];
- 執(zhí)行查詢]
執(zhí)行查詢: 使用executeQuery:方法
// 查詢數(shù)據(jù)
FMResultSet *rs = [db executeQuery:@"SELECT * FROM t_student"];
// 遍歷結(jié)果集
while ([rs next]) {
NSString *name = [rs stringForColumn:@"name"];
int age = [rs intForColumn:@"age"];
double score = [rs doubleForColumn:@"score"];
}
- FMDatabaseQueue(隊(duì)列:默認(rèn)是線程安全的)
FMDatabaseQueue: FMDatabase這個(gè)類(lèi)是線程不安全的,如果多條線程同時(shí)訪問(wèn)我
們的數(shù)據(jù)庫(kù),會(huì)造成數(shù)據(jù)紊亂等現(xiàn)象.所以,為了保證我們的線程安全問(wèn)題,
FMDB提供了安全便捷的FMDatabaseQueue類(lèi).
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:path];
- 關(guān)閉數(shù)據(jù)庫(kù)
關(guān)閉數(shù)據(jù)庫(kù): 直接調(diào)用數(shù)據(jù)庫(kù)的close方法即可:
[db close]
下面是使用FMDB的簡(jiǎn)單實(shí)例
- 使用FMDB的前提準(zhǔn)備
-
設(shè)置storyboard
Snip20160804_4.png
//
// ViewController.m
// FMDB的簡(jiǎn)單使用
//
// Created by Alex William on 16/8/4.
// Copyright ? 2016年 WeiKa. All rights reserved.
//
/*
創(chuàng)建數(shù)據(jù)庫(kù)和數(shù)據(jù)表的基本步驟:
1, 拼接保存數(shù)據(jù)庫(kù)的絕對(duì)路徑
2, 通過(guò)路徑創(chuàng)建數(shù)據(jù)庫(kù)
3, 打開(kāi)數(shù)據(jù)庫(kù)(打開(kāi)后才能執(zhí)行SQLite語(yǔ)句)
*/
#import "ViewController.h"
@interface ViewController ()
@property(nonatomic, strong) FMDatabaseQueue *queue;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 獲取沙盒的地址
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
// 拼接數(shù)據(jù)庫(kù)的全路徑
NSString *filePath = [path stringByAppendingPathComponent:@"student.sqlite"];
// 打印數(shù)據(jù)庫(kù)地址
NSLog(@"filePath =%@", filePath);
// 創(chuàng)建一個(gè)FMDatabaseQueue對(duì)象
// 只要?jiǎng)?chuàng)建了數(shù)據(jù)庫(kù)隊(duì)列對(duì)象,FMDB內(nèi)部就會(huì)自動(dòng)幫我們加載數(shù)據(jù)庫(kù)對(duì)象
self.queue = [FMDatabaseQueue databaseQueueWithPath:filePath];
// 執(zhí)行操作(內(nèi)部會(huì)通過(guò)block傳遞創(chuàng)建好的數(shù)據(jù)庫(kù)給我們)
[self.queue inDatabase:^(FMDatabase *db) {
// 創(chuàng)建表(在FMDB框架中, 增加/刪除/修改/創(chuàng)建/銷(xiāo)毀等操作都是屬于更新)
BOOL success = [db executeUpdate:@"CREATE TABLE IF NOT EXISTS t_student (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, score REAL DEFAULT 1);"];
if (success) {
NSLog(@"創(chuàng)建表成功");
} else {
NSLog(@"創(chuàng)建表失敗");
}
}];
}
// 插入
- (IBAction)insertOnClicked:(id)sender {
[self.queue inDatabase:^(FMDatabase *db) {
// 插入數(shù)據(jù)
// 在FMDB中可以使用?當(dāng)做占位符, 但是需要注意: 如果使用問(wèn)號(hào)作為占位符, 以后只能給問(wèn)號(hào)傳遞對(duì)象
BOOL success = [db executeUpdate:@"INSERT INTO t_student (id, name, score) VALUES (?, ?, ?);",@(1), @"Alex", @(99)];
if (success) {
NSLog(@"插入數(shù)據(jù)成功");
} else {
NSLog(@"插入數(shù)據(jù)失敗");
}
}];
}
// 刪除
- (IBAction)deletedOnClicked:(id)sender {
}
// 修改
- (IBAction)upDateOnCliked:(id)sender {
[self.queue inDeferredTransaction:^(FMDatabase *db, BOOL *rollback) {
BOOL success = [db executeUpdateWithFormat:@"UPDATE t_student SET score = 100 WHERE name = 'Alex';"];
if (success) {
NSLog(@"修改成功");
} else
{
NSLog(@"修改失敗");
}
}];
}
// 查詢
- (IBAction)queryOnClicked:(id)sender {
[self.queue inDatabase:^(FMDatabase *db) {
// 在FMDB框架中除了查詢所有的操作都是update操作, 而查詢操作使用的是executeQuery操作
// 在使用查詢方法時(shí),需要用到FDMB中的結(jié)果集FMResultSet
FMResultSet *results = [db executeQuery:@"SELECT id, name, score FROM t_student;"];
// next方法如果返回的是YES,說(shuō)明有數(shù)據(jù)可查, 如果返回NO說(shuō)明查詢失敗
while ([results next]) {
// 有兩種方式獲取到數(shù)據(jù)庫(kù)中的數(shù)據(jù)
/*
方式一:
int ID = [results intForColumnIndex:0];
NSString *name = [results stringForColumnIndex:1];
double score = [results doubleForColumnIndex:2];
NSLog(@"ID = %d, name = %@, score = %f", ID, name, score);
*/
// 方式二:
int ID = [results intForColumn:@"id"];
NSString *name = [results stringForColumn:@"name"];
double score = [results doubleForColumn:@"score"];
NSLog(@"ID = %d, name = %@, score = %f", ID, name, score);
}
}];
}
@end