FMDB 的使用

FMDB 是对 sqlite 的封装,该文章通过使用 FMDB 对学生数据进行操作,学习记录 FMDB 的使用。
1.首先,我们需要将 FMDB 再次封装为一个工具类,并提供一些接口供外部调用

#import <Foundation/Foundation.h>
@class Student;

@interface FMDBTool : NSObject

/**
 添加一条学生数据
 @param student student
 */
+ (void)insertStudent:(Student *)student;

/**
  添加多条学生数据
 @param students students
 */
+ (void)insertStudents:(NSArray <Student *> *)students;

/**
 更新一条学生数据
 @param student student
 */
+ (void)updateStudent:(Student *)student;

/**
 删除一条学生数据
 @param student student
 */
+ (void)deleteStudent:(Student *)student;

/**
 查询数据
 @return 查询结果
 */
+ (NSArray *)queryStudents;

@end

2.在工具类中实现上述接口

#import "FMDBTool.h"
#import "Student.h"
#import <FMDB.h>

@implementation FMDBTool

//static 保证了 _queue 无法被外部调用
static FMDatabaseQueue *_queue;

+ (void)initialize {
    //获取沙盒路径
    NSString *dbPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"FMDB_Student.sqlite"];
    NSLog(@"dbPath = %@",dbPath);
    //使用此方式可以保证线程安全
    _queue = [FMDatabaseQueue databaseQueueWithPath:dbPath];
    
    [_queue inDatabase:^(FMDatabase * _Nonnull db) {
        //创建 t_student 表, 其中 id 为主键,自增长, name 和 age 为需要存储的学生数据字段
        BOOL result = [db executeUpdate:@"create table if not exists t_student (id integer primary key autoincrement, name text, age integer);"];
        if (result) {
            NSLog(@"创建表 t_student 成功");
        } else {
            NSLog(@"创建表 t_student 失败");
        }
    }];
}

+ (void)insertStudent:(Student *)student {
    [_queue inDatabase:^(FMDatabase * _Nonnull db) {
        BOOL result = [db executeUpdate:@"insert into t_student (name, age) values (?, ?);",student.name, @(student.age)];
        if (result) {
            NSLog(@"成功插入一条学生数据 name = %@   age = %d",student.name, student.age);
        } else {
            NSLog(@"插入学生数据 name = %@   age = %d  失败!!!",student.name, student.age);
        }
    }];
}

+ (void)insertStudents:(NSArray<Student *> *)students {
    for (Student *student in students) {
        [self insertStudent:student];
    }
}

+ (void)updateStudent:(Student *)student {
    [_queue inDatabase:^(FMDatabase * _Nonnull db) {
        //更新某个学生的年龄数据
        BOOL result = [db executeUpdate:@"update t_student set age = ? where name = ? ;",@(student.age), student.name];
        if (result) {
            NSLog(@"更新学生数据 name = %@   age = %d  成功",student.name, student.age);
        } else {
            NSLog(@"更新学生数据 name = %@   age = %d  失败!!!",student.name, student.age);
        }
    }];
}

+ (void)deleteStudent:(Student *)student {
    [_queue inDatabase:^(FMDatabase * _Nonnull db) {
        BOOL result = [db executeUpdate:@"delete from t_student where name = ? and age = ? ;",student.name, @(student.age)];
        if (result) {
            NSLog(@"删除学生数据 name = %@   age = %d  成功",student.name, student.age);
        } else {
            NSLog(@"删除学生数据 name = %@   age = %d  失败!!!",student.name, student.age);
        }
    }];
}

+ (NSArray *)queryStudents {
    __block NSMutableArray *students = nil;
    
    //inDatabase 内部是一个同步线程,所以在 block 执行完毕之前,查询方法不会被提前 return
    [_queue inDatabase:^(FMDatabase * _Nonnull db) {
        students = [[NSMutableArray alloc] init];
        //查询年龄大于 20岁的学生数据, ASC为升序(默认), DESC 为降序
        FMResultSet *rs = [db executeQuery:@"select * from t_student where age > ? order by age ASC;",@(20)];
        //用 while
        while (rs.next) {
            NSString *name = [rs stringForColumn:@"name"];
            int age = [rs intForColumn:@"age"];
            
            Student *student = [[Student alloc] init];
            student.name = name;
            student.age = age;
            [students addObject:student];
        }
    }];
    
    return students;
}

@end

3.调用接口,检查是否可以正常使用

3.1 在控制器内随机生成 30条学生数据,插入到数据库内

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    NSMutableArray *students = [[NSMutableArray alloc] init];
    for (int i = 0; i < 30; i++) {
        //生成随机数据
        NSString *name = [NSString stringWithFormat:@"sdj_%d",arc4random()%50];
        int age = arc4random()%50;
        
        Student *student = [[Student alloc] init];
        student.name = name;
        student.age  = age;
        [students addObject:student];
    }
    [FMDBTool insertStudents:students];
}
沙盒路径

控制台日志

3.2 根据沙盒路径下的文件和日志输出,我们可以认为已经操作成功了。如果需要进一步确认的话,我们可以通过数据库软件打开文件查看数据是否已经插入成功,我这里使用 Navicat 进行查看。


数据已成功插入

3.3 数据插入成功后,我们开始对数据进行操作

    //将 sdj_12 的年龄改为 27
    Student *student = [[Student alloc] init];
    student.name = @"sdj_12";
    student.age = 27;
    [FMDBTool updateStudent:student];
    //删除 姓名为 sdj_27 且 年龄为 47 的学生数据
    Student *student = [[Student alloc] init];
    student.name = @"sdj_27";
    student.age = 47;
    [FMDBTool deleteStudent:student];
    //查询年龄大于 20岁的学生数据
    NSArray *students = [FMDBTool queryStudents];
    for (Student *student in students) {
        NSLog(@"%@  %d",student.name, student.age);
    }

4.以上就是对 FMDB 的简单应用,各位也可以自己查阅 FMDB 的 API,总体使用上是很方便的。

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