先上代碼
#import "FMDBManager.h"
#import <FMDB/FMDB.h>
@implementation FMDBManager {
FMDatabase *_db;
}
+ (instancetype)sharedManager {
static FMDBManager *manager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[FMDBManager alloc] init];
[manager setupDatabase];
});
return manager;
}
- (void)setupDatabase {
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *databasePath = [documentsPath stringByAppendingPathComponent:@"mydatabase.sqlite"];
_db = [FMDatabase databaseWithPath:databasePath];
if ([_db open]) {
NSString *createTableSql = @"CREATE TABLE IF NOT EXISTS mytable (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)";
if (![_db executeUpdate:createTableSql]) {
NSLog(@"創(chuàng)建表失敗:%@", [_db lastErrorMessage]);
}
} else {
NSLog(@"打開數(shù)據(jù)庫失敗:%@", [_db lastErrorMessage]);
}
}
- (void)insertDataWithDictionary:(NSDictionary *)dictionary {
NSString *name = dictionary[@"name"];
NSNumber *age = dictionary[@"age"];
NSString *insertSql = @"INSERT INTO mytable (name, age) VALUES (?, ?)";
if (![_db executeUpdate:insertSql, name, age]) {
NSLog(@"插入數(shù)據(jù)失敗:%@", [_db lastErrorMessage]);
}
}
- (NSArray *)getAllData {
NSMutableArray *result = [NSMutableArray array];
NSString *querySql = @"SELECT * FROM mytable";
FMResultSet *resultSet = [_db executeQuery:querySql];
while ([resultSet next]) {
NSInteger id = [resultSet intForColumn:@"id"];
NSString *name = [resultSet stringForColumn:@"name"];
NSInteger age = [resultSet intForColumn:@"age"];
NSDictionary *dictionary = @{@"id": @(id), @"name": name, @"age": @(age)};
[result addObject:dictionary];
}
return result;
}
- (void)deleteDataWithId:(NSInteger)id {
NSString *deleteSql = @"DELETE FROM mytable WHERE id = ?";
if (![_db executeUpdate:deleteSql, @(id)]) {
NSLog(@"刪除數(shù)據(jù)失敗:%@", [_db lastErrorMessage]);
}
}
- (void)updateDataWithDictionary:(NSDictionary *)dictionary {
NSInteger id = [dictionary[@"id"] integerValue];
NSString *name = dictionary[@"name"];
NSNumber *age = dictionary[@"age"];
NSString *updateSql = @"UPDATE mytable SET name = ?, age = ? WHERE id = ?";
if (![_db executeUpdate:updateSql, name, age, @(id)]) {
NSLog(@"更新數(shù)據(jù)失敯卫场:%@", [_db lastErrorMessage]);
}
}
@end
這個工具類名為 FMDBManager,使用了單例模式隘竭。在單例的初始化方法 setupDatabase 中塘秦,首先獲取應用程序沙盒中的 Documents 目錄,然后在該目錄下創(chuàng)建一個名為 mydatabase.sqlite 的 SQLite 數(shù)據(jù)庫文件动看,并使用 FMDatabase 類創(chuàng)建一個名為 _db 的數(shù)據(jù)庫對象尊剔。
然后,通過執(zhí)行 SQL 語句創(chuàng)建一個名為 mytable 的表菱皆。在 insertDataWithDictionary
方法中须误,使用 executeUpdate:arguments:
方法執(zhí)行插入數(shù)據(jù)的 SQL 語句。在 getAllData
方法中仇轻,使用 executeQuery:
方法執(zhí)行查詢數(shù)據(jù)的 SQL 語句京痢,得到一個 FMResultSet
對象。然后使用 while
循環(huán)遍歷查詢結果篷店,將每一行數(shù)據(jù)轉換為字典對象祭椰,并添加到一個可變數(shù)組中。最后,返回該數(shù)組方淤。
在 deleteDataWithId
方法中钉赁,使用 executeUpdate:arguments:
方法執(zhí)行刪除數(shù)據(jù)的 SQL 語句。在 updateDataWithDictionary
方法中携茂,使用 executeUpdate:arguments:
方法執(zhí)行更新數(shù)據(jù)的 SQL 語句你踩。
使用方法
// 插入數(shù)據(jù)
NSDictionary *dictionary = @{@"name": @"Tom", @"age": @18};
[[FMDBManager sharedManager] insertDataWithDictionary:dictionary];
// 查詢所有數(shù)據(jù)
NSArray *result = [[FMDBManager sharedManager] getAllData];
NSLog(@"查詢結果:%@", result);
// 刪除數(shù)據(jù)
NSInteger idToDelete = 1;
[[FMDBManager sharedManager] deleteDataWithId:idToDelete];
// 更新數(shù)據(jù)
NSDictionary *dictionaryToUpdate = @{@"id": @2, @"name": @"Jerry", @"age": @20};
[[FMDBManager sharedManager] updateDataWithDictionary:dictionaryToUpdate];
這個示例中,首先插入了一條數(shù)據(jù)邑蒋,然后查詢所有數(shù)據(jù)并輸出結果姓蜂。接著刪除了一條數(shù)據(jù)按厘,最后更新了一條數(shù)據(jù)医吊。需要注意的是,示例中的 SQL 語句都比較簡單逮京,實際開發(fā)中可能需要更加復雜的 SQL 語句來實現(xiàn)更加靈活的數(shù)據(jù)存儲和查詢卿堂。
存儲Model
.h
@interface Person : NSObject
@property (nonatomic, assign) NSInteger id;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end
.m
@implementation Person
@end
在存儲 Person 對象時,可以先將其轉換為 NSDictionary:
- (void)insertPerson:(Person *)person {
NSString *sql = @"INSERT INTO person (name, age) VALUES (?, ?)";
NSDictionary *arguments = @{@"name": person.name, @"age": @(person.age)};
BOOL success = [self.db executeUpdate:sql withParameterDictionary:arguments];
if (!success) {
NSLog(@"插入數(shù)據(jù)失敗");
}
}
在查詢 Person 對象時懒棉,可以先將查詢結果轉換為 NSDictionary 或 NSArray草描,再將其轉換為 Person 對象:
- (NSArray<Person *> *)getAllPersons {
NSString *sql = @"SELECT * FROM person";
FMResultSet *result = [self.db executeQuery:sql];
NSMutableArray *persons = [NSMutableArray array];
while ([result next]) {
NSInteger personId = [result intForColumn:@"id"];
NSString *name = [result stringForColumn:@"name"];
NSInteger age = [result intForColumn:@"age"];
Person *person = [[Person alloc] init];
person.id = personId;
person.name = name;
person.age = age;
[persons addObject:person];
}
return persons;
}
需要注意的是,在進行 Model 轉換時策严,要保證 Model 中的屬性名與數(shù)據(jù)庫中的列名一致穗慕,否則可能會出現(xiàn)錯誤。另外妻导,如果 Model 中的屬性比較復雜逛绵,如包含了數(shù)組、字典等嵌套結構倔韭,轉換可能會比較復雜术浪,需要進行適當?shù)奶幚怼?/p>