iOS数据持久化之FMDB的简单封装

缘由

FMDB是iOS平台处理数据持久化的一个强大工具,可以帮助开发者高效地在客户端处理数据,但对于我等初级开发者来说其使用还是不够简单。因此,有必要对它进行封装,从而使其更易于使用,封装的方式因人而异,需要我们根据自己的代码习惯进行优化。我的封装也仅限于提供一种简单的思路,以便后来者参考。

如何实现

我的项目名为fmdbEncap,托管于Github。在我的代码中, 使用MZDatabaseManager创建SQLite数据库;在 MZSqliteDao中创建了基于FMDB的一系列方法用于数据库创建、建表,以及数据库的增、删、改、查。
文末会附上Github项目地址

如何使用

关于如何在你的项目中使用该封装,你只需在引入FMDB的前提下添加本项目中的FMDBEncapsulation文件夹和相关模型数据即可。

一些说明

为了使它简单实用,项目中包含fmdb_taskfmdb_category两个表用于举例说明,表中的参数也与代码中实例一一对应。SQLite数据库建立在Documents路径下,对数据库的一切操作基于模拟数据。我会尽量涵盖FMDB基本使用的相关细节,并将持续更新代码。

SQL 语句

SQL语句以宏定义的形式在配置文件中写入。

  • Table Name
#define     TABLE_TASK                   @"FMDB_TASK"
#define     TABLE_CATEGORY               @"FMDB_CATEGORY"
  • Create tables
#define     SQL_CREATE_TASK              @"CREATE TABLE IF NOT EXISTS FMDB_TASK(\
                                           TASK_ID integer PRIMARY KEY AUTOINCREMENT NOT NULL,\
                                           ROOM_ID int(11) NOT NULL DEFAULT 0,\
                                           TASK_INFO int(11),\
                                           TASK_NUMBER int(4) NOT NULL,\
                                           TASK_STATUS int(4) NOT NULL,\
                                           TASK_COORDINATE varchar(20),\
                                           TASK_BEDSIDE varchar(20)\
                                           );"

#define     SQL_CREATE_CATEGORY          @"CREATE TABLE IF NOT EXISTS FMDB_CATEGORY(\
                                           CATEGORY_ID integer PRIMARY KEY AUTOINCREMENT NOT NULL,\
                                           PARENT_ID int(11) NOT NULL,\
                                           LEVEL int(11),\
                                           CATEGORY_NAME nvarchar(45) NOT NULL,\
                                           CATEGORY_IMG varchar(100),\
                                           CATEGORY_RANK int(11) NOT NULL,\
                                           CATEGORY_TYPE int(4) NOT NULL,\
                                           CATEGORY_STATUS int(11) NOT NULL,\
                                           CATEGORY_REMARK nvarchar(100)\
                                           );"                                           
  • Insert
#define     SQL_INSERT_TASK              @"INSERT INTO FMDB_TASK\
                                           ( ROOM_ID, TASK_INFO, TASK_NUMBER,\
                                           TASK_STATUS, TASK_COORDINATE, TASK_BEDSIDE)\
                                           VALUES ( '%d', '%d', '%d', '%d', '%@', '%@');"

#define     SQL_INSERT_CATEGORY          @"INSERT INTO FMDB_CATEGORY\
                                           ( PARENT_ID, LEVEL, CATEGORY_NAME, CATEGORY_IMG,\
                                           CATEGORY_RANK, CATEGORY_TYPE, CATEGORY_STATUS, CATEGORY_REMARK)\
                                           VALUES ( '%d', '%d', '%@', '%d', '%d', '%d', '%d', '%@');"

#define     SQL_INSERT_TASK_PARAMTER     @"INSERT INTO FMDB_TASK\
                                           ( ROOM_ID, TASK_INFO, TASK_NUMBER,\
                                           TASK_STATUS, TASK_COORDINATE, TASK_BEDSIDE)\
                                           VALUES (\
                                           :roomID, :taskInfo, :taskNumber, :taskStatus, :taskCoordinate, :taskBeside);"

#define     SQL_INSERT_CATEGORY_PARAMTER @"INSERT INTO FMDB_CATEGORY\
                                           ( PARENT_ID, LEVEL, CATEGORY_NAME, CATEGORY_IMG,\
                                           CATEGORY_RANK, CATEGORY_TYPE, CATEGORY_STATUS, CATEGORY_REMARK)\
                                           VALUES (\
                                           :prantID, :level, :categoryName, :categoryImage, :categoryRank, :categoryType, :categoryStatus, :categoryRemark);"
  • Update
#define     SQL_UPDATE_TASK              @"UPDATE FMDB_TASK\
                                           SET ROOM_ID = '%d', TASK_INFO = '%d', TASK_NUMBER = '%d',\
                                           TASK_STATUS = '%d', TASK_COORDINATE = '%@', TASK_BEDSIDE = '%@'\
                                           WHERE TASK_ID = '%d';"

#define     SQL_UPDATE_CATEGORY          @"UPDATE FMDB_CATEGORY\
                                           SET PARENT_ID = '%d', LEVEL = '%d', CATEGORY_NAME = '%@',\
                                           CATEGORY_IMG = '%d',CATEGORY_RANK = '%d', CATEGORY_TYPE = '%d',\
                                           CATEGORY_STATUS = '%d',CATEGORY_REMARK = '%@'\                                           WHERE CATEGORY_ID = '%d';"
  • Delete
#define     SQL_DELETE                   @"DELETE FROM %@ WHERE '%@'='%d';"

#define     SQL_DELETE_ALL               @"DELETE FROM %@"
  • Select
#define     SQL_SELECT_ALL               @"SELECT * FROM %@;"

#define     SQL_SELECT_PARAMTER          @"SELECT * FROM %@ WHERE %@ = '%d';"

举例说明


1.Create database

[[MZDatabaseManager sharedInstance] createDatabaseWithName:@"test"];

2.Create table

self.sqliteDao = [[MZSqliteDao alloc] init];
// create table
[self.sqliteDao createTable:TABLE_TASK withSQL:SQL_CREATE_TASK];
[self.sqliteDao createTable:TABLE_CATEGORY withSQL:SQL_CREATE_CATEGORY];

3.Insert

NSArray *arrayOfTasks = [MZTask taskMetedata];
    NSArray *arrayOfCategories = [MZCategory categoryMetedata];
    
      // task: SQL 语句拼接
    for (MZTask *task in arrayOfTasks) {
        NSString *SQL_InsertTaskData = [NSString stringWithFormat:SQL_INSERT_TASK,[task.roomID intValue],[task.taskInfo  intValue],[task.taskNumber  intValue],[task.taskStatus  intValue],task.taskCoordinate,task.taskBeside];
        BOOL success = [self.sqliteDao excuteSQL:SQL_InsertTaskData];
        if (success) {
            NSLog(@"insert success!");
        }
    }
      // category: 带参
    for (NSInteger i = 0; i < arrayOfCategories.count; i ++) {
        MZCategory *category = arrayOfCategories[i];
        NSDictionary *paramDict = @{@"prantID":category.parentID,
                                    @"level":category.level,
                                    @"categoryName":category.categoryName,
                                    @"categoryImage":category.categoryImg,
                                    @"categoryRank":category.categoryRank,
                                    @"categoryType":category.categoryType,
                                    @"categoryStatus":category.categoryStatus,
                                    @"categoryRemark":category.categoryRemark
                                    };
        BOOL success = [self.sqliteDao excuteSQL:SQL_INSERT_CATEGORY_PARAMTER withDicParameter:paramDict];
        if (success) {
            NSLog(@"%@ insert success!",paramDict);
        }
    }

4.Update

NSString *SQL_UpdateTaskData = [NSString stringWithFormat:SQL_UPDATE_TASK, 10, 10, 10, 10,@"la",@"la", 10];
[self.sqliteDao excuteSQL:SQL_UpdateTaskData];

5.Delete

//NSString *SQL_DeleteAllTaskData = [NSString stringWithFormat:SQL_DELETE_ALL,TABLE_TASK];
// delete one record
    NSString *SQL_DeleteTaskData = [NSString stringWithFormat:SQL_DELETE,TABLE_TASK,@"TASK_ID",248];
    BOOL deleteSuccess = [self.sqliteDao excuteSQL:SQL_DeleteTaskData];
    if (deleteSuccess) {
        NSLog(@"delete success!");
    }

6.Select

NSString *SQL_SelectCategoryData = [NSString stringWithFormat:SQL_SELECT_ALL,TABLE_TASK];
    NSMutableArray *selectedTasks = [NSMutableArray array];
    // select *
    [self.sqliteDao excuteQuerySQL:SQL_SelectCategoryData resultBlock:^(FMResultSet *rsSet) {
        while ([rsSet next]) {
            NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
            [dict setValue:[rsSet objectForColumnName:@"TASK_ID"] forKey:@"TASK_ID"];
            [dict setValue:[rsSet objectForColumnName:@"ROOM_ID"] forKey:@"ROOM_ID"];
            [dict setValue:[rsSet objectForColumnName:@"TASK_INFO"] forKey:@"TASK_INFO"];
            [dict setValue:[rsSet objectForColumnName:@"TASK_NUMBER"] forKey:@"TASK_NUMBER"];
            [dict setValue:[rsSet objectForColumnName:@"TASK_STATUS"] forKey:@"TASK_STATUS"];
            [dict setValue:[rsSet objectForColumnName:@"TASK_COORDINATE"] forKey:@"TASK_COORDINATE"];
            [dict setValue:[rsSet objectForColumnName:@"TASK_BEDSIDE"] forKey:@"TASK_BEDSIDE"];
            [selectedTasks addObject:dict];
        }
    }];
    NSLog(@"selected all tasks:%@",selectedTasks);
    // select by ID
    NSString *SQL_SelectByID = [NSString stringWithFormat:SQL_SELECT_PARAMTER,TABLE_CATEGORY,@"CATEGORY_ID",6];
    [self.sqliteDao excuteQuerySQL:SQL_SelectByID resultBlock:^(FMResultSet *rsSet) {
        while ([rsSet next]) {
            // save as model data
            MZCategory *selectedCategory    = [MZCategory new];
            selectedCategory.categoryID     = [rsSet objectForColumnName:@"CATEGORY_ID"];
            selectedCategory.parentID       = [rsSet objectForColumnName:@"PARENT_ID"];
            selectedCategory.level          = [rsSet objectForColumnName:@"LEVEL"];
            selectedCategory.categoryName   = [rsSet objectForColumnName:@"CATEGORY_NAME"];
            selectedCategory.categoryImg    = [rsSet objectForColumnName:@"CATEGORY_IMG"];
            selectedCategory.categoryRank   = [rsSet objectForColumnName:@"CATEGORY_RANK"];
            selectedCategory.categoryType   = [rsSet objectForColumnName:@"CATEGORY_TYPE"];
            selectedCategory.categoryStatus = [rsSet objectForColumnName:@"CATEGORY_STATUS"];
            selectedCategory.categoryRemark = [rsSet objectForColumnName:@"CATEGORY_REMARK"];
            NSLog(@"select by categoryID:%d,parentID:%d,level:%d,categoryName:%@,categoryImg:%@,categoryRank:%d,categoryType:%d,categoryStatus:%d,categoryRemark:%@",[selectedCategory.categoryID intValue],[selectedCategory.parentID intValue],[selectedCategory.level intValue],selectedCategory.categoryName,selectedCategory.categoryImg,[selectedCategory.categoryRank intValue],[selectedCategory.categoryType intValue],[selectedCategory.categoryStatus intValue],selectedCategory.categoryRemark);
        }
    }];

说在后面

本人技术浅薄,对数据库的理解也不够深入透彻,在此写下微末经验,以期为后来之初学者提供些许便利,若有一人觉得此项目并非通篇胡言,也不枉我码字之劳累,最后奉上Github项目地址,如需参考不妨前往下载。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,565评论 25 707
  • 遇见既是预见,预见方能遇见。心菲梵:一个致力于生命身心灵成长的平台。她的发起人水晶老师是一个如水晶般通透纯净...
    a小调奏鸣曲阅读 177评论 0 0
  • 晚上 ,纳西小伙领队带我们来到村里一户摩梭人家,祖母房里的家宴,我们喝到了苏浬玛酒,吃过了肥而不腻的猪膘肉。原来是...
    未来的你在未来等你阅读 328评论 0 0
  • 今夜是城市的庆典,街道灯火通明。 一群孩童围绕在一个中年男人身边,他身着银色外套,手中木棍上插满大大小小的喇叭。 ...
    Marvin1379阅读 184评论 0 0