美文网首页
FMDB的简单概述

FMDB的简单概述

作者: 苍茫的天涯 | 来源:发表于2017-04-06 18:28 被阅读28次

    这篇博客主要是用来简单介绍一下FMDB的基础用法,涉及到简单的增删改查

    一:FMDB介绍

    FMDB是一种第三方的开源库,FMDB就是对SQLite的API进行了封装,加上了面向对象的思想,简单来说就是让我们能更方遍的操作SQLite更加方便。

    FMDB优点:

    • 使用起来更加面向对象,省去了很多麻烦、冗余的C语言代码
    • 对比苹果自带的CoreData框架,更加轻量级和灵活
    • 提供多线程安全,有效地防止数据混乱,原来的SQLite不是线程安全的

    使用FMDB需要的步骤:

    1. 项目中添加libsqlite3库的依赖
    2. 推荐直接使用cocoapods导入到项目当中
    3. 在需要用到的类中导入FMDB的头文件 #import "FMDatabase.h"

    二:FMDB的使用

    FMDB的具体步骤我简单的归类为一下几个小点,下面会一一描述相应的citydb就是城市的数据库:

    1. 创建数据库
    2. 打开数据库
    3. 创建相应的库表
    4. 对库表进行操作
    5. 对查出数据的解析
    6. 关闭数据库

    1:创建数据库的方法

    根据FMDB官方的注解翻译过来的意思就是

    /*
     1. 这个文件不一定必须存在沙盒中,所以如果已经存在的话就直接使用,不存在就会帮你创建一个;
     2. 你可以选择直接传空的字符串,那么系统会在临时目录创建一个空的数据库,当数据库关闭时,该数据库文件也被删除;
     3. 如果传nil,会在内存中临时创建一个空的数据库,当数据库关闭时,数据库文件也被删除;
    */
    + (FMDatabase *)databaseWithPath:(NSString *)filePath;
    

    相应的实现方法是:

    NSString *DocumentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    NSString *dbPath = [DocumentPath stringByAppendingPathComponent:@"data.db"];
    FMDatabase *citydb = [FMDatabase databaseWithPath:dbPath];
    

    2:打开数据库

    /*
    打开数据库,一般用法是在查询语句之前调用一下,返回值是BOOL类型,这个BOOL的意思是告诉你这次打开是否成功,然后打开成功以后你就能对你的数据库进行操作了
    */
    [citydb open];
    
    

    3:创建库表

    这里额外说明一下,[citydb executeUpdate:sql];这句话用的是executeUpdate方法,因为添加库表可以理解为更新数据库的行为,所以executeUpdate是可行的,同时用executeStatements方法也是同样可行的,executeStatements简单理解就是让数据库运行这个方法里的行为。

        FMDatabase * db = [FMDatabase databaseWithPath:self.dbPath];
        if ([db open]) {
            NSString *sql = @"create table if not exists city(cityName text, cityId text, userId text);";
            [citydb executeUpdate:sql];
        }
        
    

    4:对数据库进行操作

    /* 执行更新的SQL语句,字符串里面的"?",依次用后面的参数替代,必须是对象,不能是int等基本类型 */
    - (BOOL)executeUpdate:(NSString *)sql,... ;
    /* 执行更新的SQL语句,可以使用字符串的格式化进行构建SQL语句 */
    - (BOOL)executeUpdateWithFormat:(NSString*)format,... ;
    /* 执行更新的SQL语句,字符串中有"?",依次用arguments的元素替代 */
    - (BOOL)executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments;
    

    下面我在列举一下简单的增删改查四个方法

    增加字段到city

    FMDatabase * db = [FMDatabase databaseWithPath:self.dbPath];
        if ([db open]) {
            BOOL res = NO;
            NSDictionary *cityDic = @{@"杭州":@"1",@"上海":@"2",@"宁波":@"3",@"温州":@"4",@"台州":@"5",@"湖州":@"6",@"绍兴":@"7",@"金华":@"8"};
            for (NSString *key in cityDic.allKeys) {
                NSString *sqlStr = [NSString stringWithFormat:@"insert into city(cityName,cityId,userId)values('%@','%@','%@')",key,cityDic[key],@"123"];
                res = [db executeUpdate:sqlStr];
            }
            if (!res) {
                NSLog(@"error to insert  city");
            } else {
                NSLog(@"success to insert  city");
            }
            [db close];
        }
    

    删除city表中,cityName为“杭州” 且cityId为“1”的字段

    FMDatabase *db = [FMDatabase databaseWithPath:self.dbPath];
        if ([db open]) {
            NSString *sql = [NSString stringWithFormat:@"delete from city where cityName = '%@' and cityId = '%@'",@"杭州",@"1"];
            BOOL rs = [db executeUpdate:sql];
            if (!rs) {
                NSLog(@"error to update city");
            } else {
                NSLog(@"success to update city");
            }
            
            [db close];
        }
    

    修改city表中,cityId为“2”的字段

    FMDatabase * db = [FMDatabase databaseWithPath:self.dbPath];
        if ([db open]) {
            NSString *sqlStr = [NSString stringWithFormat:@"update city set cityName = '%@' where cityId = '2'",self.textField.text];
            BOOL res = [db executeUpdate:sqlStr];
            if (!res) {
                NSLog(@"error to insert  city");
            } else {
                NSLog(@"success to insert  city");
            }
            [db close];
        }
    

    查询city表中的所有字段

    FMDatabase *db = [FMDatabase databaseWithPath:self.dbPath];
        if ([db open]) {
            NSMutableDictionary *mutableDic = [[NSMutableDictionary alloc] init];
            NSString *sql = [NSString stringWithFormat:@"select * from city where userId = '%@'",@"123"];
            FMResultSet *rs = [db executeQuery:sql];
            while ([rs next]) {
                NSString *name = [rs stringForColumn:@"cityName"];
                NSString *cityId = [rs stringForColumn:@"cityId"];
                [mutableDic setObject:cityId forKey:name];
            }
            [db close];
            NSLog(@"%@",mutableDic);
        }
    

    5:对查出的数据的解析

    在得到查出的数据以后,需要对数据进行一些对应的解析,根据数据的类型要分别处理

    /* 获取下一个记录 */
    - (BOOL)next;
    /* 获取记录有多少列 */
    - (int)columnCount;
    /* 通过列名得到列序号,通过列序号得到列名 */
    - (int)columnIndexForName:(NSString *)columnName;
    - (NSString *)columnNameForIndex:(int)columnIdx;
    /* 获取存储的整形值 */
    - (int)intForColumn:(NSString *)columnName;
    - (int)intForColumnIndex:(int)columnIdx;
    /* 获取存储的长整形值 */
    - (long)longForColumn:(NSString *)columnName;
    - (long)longForColumnIndex:(int)columnIdx;
    /* 获取存储的布尔值 */
    - (BOOL)boolForColumn:(NSString *)columnName;
    - (BOOL)boolForColumnIndex:(int)columnIdx;
    /* 获取存储的浮点值 */
    - (double)doubleForColumn:(NSString *)columnName;
    - (double)doubleForColumnIndex:(int)columnIdx;
    /* 获取存储的字符串 */
    - (NSString *)stringForColumn:(NSString *)columnName;
    - (NSString *)stringForColumnIndex:(int)columnIdx;
    /* 获取存储的日期数据 */
    - (NSDate *)dateForColumn:(NSString *)columnName;
    - (NSDate *)dateForColumnIndex:(int)columnIdx;
    /* 获取存储的二进制数据 */
    - (NSData *)dataForColumn:(NSString *)columnName;
    - (NSData *)dataForColumnIndex:(int)columnIdx;
    /* 获取存储的UTF8格式的C语言字符串 */
    - (const unsigned cahr *)UTF8StringForColumnName:(NSString *)columnName;
    - (const unsigned cahr *)UTF8StringForColumnIndex:(int)columnIdx;
    /* 获取存储的对象,只能是NSNumber、NSString、NSData、NSNull */
    - (id)objectForColumnName:(NSString *)columnName;
    - (id)objectForColumnIndex:(int)columnIdx;
    

    6:数据库表的关闭

    /*
    关闭数据库,在你对数据库的操作完成以后要记得关闭数据库
    */
    [citydb close];
    
    

    三:一些注意事项

    下面要讲一讲我在学习FMDB的时候遇到的一些问题,给我的感觉呢,FMDB在Xcode中编写其实还是挺糟心的。因为你会发现有时候稍微写错一点点东西,就能让你整个方法崩溃,有可能一个简单的(')就让你整句查询语句说拜拜= =,而且Xcode不会告诉你到底是哪里出了问题,这就让人很难过了,所以你能做到的只有孰能生巧,不断的让自己熟练,少犯这样的低级错误。

    在执行查询语句的时候一定要用- (BOOL)next 方法,就算你只查一个数据,也一定要用

    错误的示范(因为只查一个数据,所以自以为是的没用next方法,然后GG了(╯‵□′)╯︵┻━┻)

    if ([db open]) {
            NSString *sql = [NSString stringWithFormat:@"select * from city where cityId = '%@'",@"2"];
            FMResultSet *rs = [db executeQuery:sql];
            NSString *name = [rs stringForColumn:@"cityName"];
            [db close];
        }
    

    正确的姿势应该是这样的

    if ([db open]) {
            NSString *sql = [NSString stringWithFormat:@"select * from city where cityId = '%@'",@"2"];
            FMResultSet *rs = [db executeQuery:sql];
            while ([rs next]) {
                NSString *name = [rs stringForColumn:@"cityName"];
            }
            [db close];
        }
    

    另外就是,在操作数据库的时候,大家一定要注意多线程的问题
    FMDatabase这个类是线程不安全的,如果在多个线程同时使用一个FMDatabase实例,会造成数据混乱问题。
    为了保证线程安全,FMDB提供方便快捷的FMDatabaseQueue类,要使用这个类,需要#import导入头文件"FMDatabaseQueue.h"FMDatabaseQueue类的操作大多都和FMDatabase很相似

    最后要感谢一下同事陪我把这些东西一起弄懂,也学会了挺多,阿弥陀佛~

    相关文章

      网友评论

          本文标题:FMDB的简单概述

          本文链接:https://www.haomeiwen.com/subject/cmiqattx.html