寫這個Blog的目的是為了記錄的學習經歷,程式碼寫的不是很好,希望讀者理解。 日常對資料庫的操作,需要設計欄位,感覺太繁瑣了,想找個簡化的方法,就想通過這樣進行實現,這也就是一種思考方式。實際實現還是看需求。具體看程式碼: 1、匯入FMDB
import FMDB
複製程式碼
2、使用單利模式和必要屬性
static let defaultManger = WDDataBaseManager()
typealias successBlock = () ->Void
typealias failBlock = () ->Void
private var tableName:String?
複製程式碼
3、懶載入建立資料庫(名稱我隨便取得)
lazy var fmdb:FMDatabase = {
let path = NSHomeDirectory().appending("/Documents/testDB.db")
let db = FMDatabase(path: path)
return db
}()
複製程式碼
4、建立表
func creatTable(tableName:String) -> Void {
fmdb.open()
self.tableName = tableName
let creatSql = "create table if not exists \(tableName) (id integer primary key autoincrement,model BLOB)"
let result = fmdb.executeUpdate(creatSql, withArgumentsIn:[])
if result{
print("建立表成功")
}
}
複製程式碼
5、刪除表
func dropTable() -> Void {
let sql = "drop table if exists " + tableName!
let result = fmdb.executeUpdate(sql, withArgumentsIn:[])
if result{
print("刪除表成功")
}
}
複製程式碼
6、插入資料
func insert(model:NSObject, successBlock: successBlock, failBlock: failBlock) -> Void {
let modelData = try! NSKeyedArchiver.archivedData(withRootObject: model, requiringSecureCoding: false)
let insertSql = "insert into " + tableName! + " (model) values(?)"
do {
try fmdb.executeUpdate(insertSql, values: [modelData])
successBlock()
} catch {
print(fmdb.lastError())
failBlock()
}
}
複製程式碼
7、更新表
func update(model:NSObject,uid:Int32, successBlock: successBlock, failBlock: failBlock) -> Void {
let modelData = try! NSKeyedArchiver.archivedData(withRootObject: model, requiringSecureCoding: false)
let updateSql = "update " + tableName! + " set model = ? where id = ?"
do {
try fmdb.executeUpdate(updateSql, values: [modelData, uid])
successBlock()
} catch {
print(fmdb.lastError())
failBlock()
}
}
複製程式碼
8、查詢資料(這是查詢所有資料,其他按需求設計)
func selectAll() -> [NSObject] {
var tmpArr = [NSObject]()
let selectSql = "select * from " + tableName!
do {
let rs = try fmdb.executeQuery(selectSql, values:nil)
while rs.next() {
var model = NSObject()
let modelData = rs.data(forColumn:"model")
let id = rs.int(forColumn: "id")
model = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(modelData!) as! NSObject
model.wd_fmdb_id = id
tmpArr.append(model)
}
} catch {
print(fmdb.lastError())
}
return tmpArr
}
複製程式碼
9、刪除資料(這是根據Id刪除的)
func delete(uid:Int32, successBlock: successBlock, failBlock: failBlock) -> Void {
let deleteSql = "delete from " + tableName! + " where id = ?"
do {
try fmdb.executeUpdate(deleteSql, values: [uid])
successBlock()
} catch {
print(fmdb.lastError())
failBlock()
}
}
複製程式碼
10、新增分類新增預設Id
private var wd_id_key: String = "key"
extension NSObject {
open var wd_fmdb_id:Int32? {
get {
return (objc_getAssociatedObject(self, &wd_id_key) as? Int32)
} set(newValue) {
objc_setAssociatedObject(self, &wd_id_key, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN)
}
}
}
複製程式碼
11、使用方法
//1. 在Appdelegate中開啟資料庫
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
DataBaseManager.defaultManger.creatTable()
return true
}
//2、新增資料
WDDataBaseManager.defaultManger.insert(model: model, successBlock: {
print("成功")
}, failBlock: {
print("失敗")
})
//3、修改資料
WDDataBaseManager.defaultManger.update(model: model, uid: self.model!.wd_fmdb_id!, successBlock: {
print("成功")
}, failBlock: {
print("失敗")
})
//4、刪除資料
WDDataBaseManager.defaultManger.delete(uid: model.wd_fmdb_id!, successBlock: {
print("成功")
}, failBlock: {
print("失敗")
})
// 5、查詢資料
WDDataBaseManager.defaultManger.selectAll()
複製程式碼
- 遵循NSCoding 重寫三個方法
import UIKit
class Model: NSObject , NSCoding{
public var name:String?
public var phone:String?
public var addres:String?
override init() {
super.init()
}
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: "name")
aCoder.encode(phone, forKey: "phone")
aCoder.encode(addres, forKey: "addres")
}
required init?(coder aDecoder: NSCoder) {
super.init()
self.name = aDecoder.decodeObject(forKey: "name") as? String
self.addres = aDecoder.decodeObject(forKey: "addres") as? String
self.phone = aDecoder.decodeObject(forKey: "phone") as? String
}
}
複製程式碼
12、效果圖
14、Demo地址:https://github.com/wudan-ios/FMDB-Model.git補充Objective-C版本 1、介面檔案
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSObject (addId)
@property (nonatomic) NSInteger wd_fmdb_id;
@end
typedef void(^successBlock)(void);
typedef void(^failBlock)(void);
@interface WDDataBaseManager : NSObject
+ (instancetype)manager;
/** 建立表 */
- (void)createTableWithName:(NSString *)name;
/** 刪除表 */
- (void)dropTable;
/** 新增資料 */
- (void)insertDataWithModel:(NSObject *)model successBlock:(successBlock)aSuccessBlock failBlock:(failBlock)aFailBlock;
/** 更新資料 */
- (void)updateDataWithModel:(NSObject *)model uid:(NSInteger)aUid successBlock:(successBlock)aSuccessBlock failBlock:(failBlock)aFailBlock;
/** 刪除資料 */
- (void)deleteDataWithUid:(NSInteger)uid successBlock:(successBlock)aSuccessBlock failBlock:(failBlock)aFailBlock;
/** 查詢全部資料 */
- (NSArray<NSObject *> *)queryAllData;
@end
NS_ASSUME_NONNULL_END
複製程式碼
2、實現檔案
#import "WDDataBaseManager.h"
#import <FMDB.h>
#import <objc/runtime.h>
static char *wd_id_key = "key";
@implementation NSObject (addId)
- (NSInteger)wd_fmdb_id {
NSNumber *numberValue = objc_getAssociatedObject(self, wd_id_key);
return numberValue.integerValue;
}
- (void)setWd_fmdb_id:(NSInteger)wd_fmdb_id {
objc_setAssociatedObject(self, wd_id_key, @(wd_fmdb_id), OBJC_ASSOCIATION_ASSIGN);
}
@end
@interface WDDataBaseManager ()
@property (nonatomic, strong) FMDatabase *fmdb;
@property (nonatomic, copy) NSString *tableName;
@end
@implementation WDDataBaseManager
+ (instancetype)manager {
static dispatch_once_t onceToken;
static WDDataBaseManager *manager = nil;
dispatch_once(&onceToken, ^{
manager = [[WDDataBaseManager alloc] init];
});
return manager;
}
- (void)createTableWithName:(NSString *)name {
[self.fmdb open];
self.tableName = name;
NSString *sql = [NSString stringWithFormat:@"create table if not exists %@ (id integer primary key autoincrement,model BLOB)", name];
BOOL result = [self.fmdb executeUpdate:sql];
if (result) {
NSLog(@"表建立成功");
}
}
- (void)dropTable {
NSString *sql = [NSString stringWithFormat:@"drop table if exists %@", self.tableName];
BOOL result = [self.fmdb executeUpdate:sql];
if (result) {
NSLog(@"表刪除成功");
}
}
- (void)insertDataWithModel:(NSObject *)model successBlock:(successBlock)aSuccessBlock failBlock:(failBlock)aFailBlock {
NSData *modelData = [NSKeyedArchiver archivedDataWithRootObject:model];
NSString *sql = [NSString stringWithFormat:@"insert into %@ (model) values(?)", self.tableName];
BOOL result = [self.fmdb executeUpdate:sql withArgumentsInArray:@[modelData]];
if (result) {
aSuccessBlock();
} else {
aFailBlock();
}
}
- (void)updateDataWithModel:(NSObject *)model uid:(NSInteger)aUid successBlock:(successBlock)aSuccessBlock failBlock:(failBlock)aFailBlock {
NSData *modelData = [NSKeyedArchiver archivedDataWithRootObject:model];
NSString *sql = [NSString stringWithFormat:@"update %@ set model = ? where id = ?", self.tableName];
BOOL result = [self.fmdb executeUpdate:sql withArgumentsInArray:@[modelData, @(aUid)]];
if (result) {
aSuccessBlock();
} else {
aFailBlock();
}
}
- (void)deleteDataWithUid:(NSInteger)uid successBlock:(successBlock)aSuccessBlock failBlock:(failBlock)aFailBlock {
NSString *sql = [NSString stringWithFormat:@"delete from %@ where id = ?", self.tableName];
BOOL result = [self.fmdb executeUpdate:sql withArgumentsInArray:@[@(uid)]];
if (result) {
aSuccessBlock();
} else {
aFailBlock();
}
}
- (NSArray<NSObject *> *)queryAllData {
NSMutableArray *array = [NSMutableArray array];
NSString *sql = [NSString stringWithFormat:@"select * from %@",self.tableName];
@try {
FMResultSet *rs = [self.fmdb executeQuery:sql];
while (rs.next) {
NSObject *model = [[NSObject alloc] init];
NSData *modelData = [rs dataForColumn:@"model"];
int uid = [rs intForColumn:@"id"];
model = [NSKeyedUnarchiver unarchiveObjectWithData:modelData];
model.wd_fmdb_id = uid;
[array addObject:model];
}
} @catch (NSException *exception) {
NSLog(@"%@", self.fmdb.lastError);
} @finally {
NSLog(@"查詢資料");
}
return array;
}
- (FMDatabase *)fmdb {
if (!_fmdb) {
NSString *path = [NSHomeDirectory() stringByAppendingString:@"/Documents/testDB.db"];
_fmdb = [[FMDatabase alloc] initWithPath:path];
}
return _fmdb;
}
@end
複製程式碼
3、使用方法
// 1、開啟資料庫,並建立表
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[WDDataBaseManager manager] createTableWithName:@"test"];
return YES;
}
// 2、新增資料
[[WDDataBaseManager manager] insertDataWithModel:model successBlock:^{
// TODO:
} failBlock:^{
// TODO:
}];
// 3、查詢資料
[[WDDataBaseManager manager] queryAllData]
// 4、修改資料
[[WDDataBaseManager manager] updateDataWithModel:model uid:self.model.wd_fmdb_id successBlock:^{
// TODO:
} failBlock:^{
// TODO:
}];
// 5、刪除資料
[[WDDataBaseManager manager] deleteDataWithUid:model.wd_fmdb_id successBlock:^{
// TODO:
} failBlock:^{
// TODO:
}];
// 6、刪除表
[[WDDataBaseManager manager] dropTable];
複製程式碼
- 插入表中的Model需要遵循(例項程式碼)
- (void)encodeWithCoder:(nonnull NSCoder *)aCoder {
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeObject:self.phone forKey:@"phone"];
[aCoder encodeObject:self.address forKey:@"address"];
}
- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder {
if (self == [super init]) {
self.name = [aDecoder decodeObjectForKey:@"name"] ;
self.phone = [aDecoder decodeObjectForKey:@"phone"];
self.address = [aDecoder decodeObjectForKey:@"address"];
}
return self;
}
複製程式碼