BGFMDB让数据的增删改查分别只需要一行代码即可,就是这么简单任性,本库几乎支持存储ios所有基本的自带数据类型.
Clone or download
huangzhibiao 增加demo事务说明
增加demo事务说明
Latest commit 7a93926 Dec 6, 2018
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
BGFMDB.xcodeproj 增加demo事务说明 Dec 6, 2018
BGFMDB 增加demo事务说明 Dec 6, 2018
BGFMDBTests 重新封装抽取了FMDB Sep 28, 2016
BGFMDBUITests 重新封装抽取了FMDB Sep 28, 2016
.DS_Store 修复线程池bug. Sep 20, 2018
.swift-version 修复模拟器上的运行错误问题. Mar 10, 2017
BGFMDB.podspec 增加demo事务说明 Dec 6, 2018
README.md 更新使用说明. May 29, 2018

README.md

BGFMDB让数据的增删改查分别只需要一行代码即可,就是这么简单任性.

最新重大更新:

1.增加了自定义“联合主键”的功能.
2.进行了大重构,优化缩减API,支持多个'唯一约束',ignoredKeys放到模型类.m文件实现bg_ignoreKeys类函数即可,增加自定义表名功能.

Swift工程中使用方式

目前可以存储Swift工程中的OC类model,在桥接文件导入OC类model的头文件即可, 但是不能解析存储Swift类model,后面会补上Swift类model解析部分😊.

小伙伴们的使用反馈

BGFMDB

交流QQ群:

使用交流QQ群: 572359447
如果在使用过程中发现什么问题或有什么疑问,请加群反馈.

完美支持:

int,long,signed,float,double,NSInteger,CGFloat,BOOL,NSString,NSMutableString,NSMutableAttributedString,NSAttributedString,NSNumber,NSArray,NSMutableArray,NSDictionary,NSMutableDictionary,NSMapTable,NSHashTable,NSData,NSMutableData,UIImage,NSDate,NSURL,NSRange,CGRect,CGSize,CGPoint,自定义对象 等的存储.

写本库的动机: 在对coredata和realm做了探究总结后,发现了很多有缺陷的地方,最明显的就是下面的原因:

realm缺陷:

Realm不支持集合类型,这一点也是比较蛋疼。
Realm支持以下的属性类型:BOOL、bool、int、NSInteger、long、long long、float、double、NSString、NSDate、NSData以及 被特殊类型标记的NSNumber。CGFloat属性的支持被取消了,因为它不具备平台独立性。
这里就是不支持集合,比如说NSArray,NSMutableArray,NSDictionary,NSMutableDictionary,NSSet,NSMutableSet。如果服务器传来的一个字典,key是一个字符串,对应的value就是一个数组,这时候就想存储这个数组就比较困难了。

coredata缺陷:

coredata虽然通过Transformable可以存取集合类型,但需要开发者去进行转换处理,使用起来不方便直观,虽然coredata有很多好用的封装库,像ResKit,MMRecord等,但这些库比较庞大,而且都是英文介绍,不利于国内初中级开发的快速开发使用.

虽然国内也已经有了对FMDB面相对象层的封装,比如像JRDB,LKDBHelper等,但是在使用总结后还是发现不少的问题,问题如下:

JRDB存储数组需要传入对象的泛型,同时还要复写一些函数和映射,这对于初中级开发者是很不利的,看的很萌逼.
LKDBHelper好一点,但也要复写不少的函数,而且LKDBHelper的使用demo有点乱,还有就是不支持NSMaptable,NSHashTable的存储,LKDBHelper还有一个致命的弱点就是当类变量名称跟sqlite的关键字一样时,会发生冲突错误!

而最重要的是: JRDB,LKDBHelper都不支持同一数组中存储不同类型的自定义类型数据,BGFMDB则完美支持,JRDB,LKDBHelper已经成为过去,现在是BGFMDB的时代,作者的宣言是:“要把BGFMDB写成不会写代码的人都会用的库”,欢迎大家反馈和吐槽问题,骚年作者等着你们.

综合上述原因后,我决定写一款适合国内初中级开发者使用的存储封装库(BGFMDB),不管是从使用步骤还是支持的存储类型上,都比JRDB,LKDB简单好用和全面.

本库几乎支持存储ios所有基本的自带数据类型.

使用介绍(喜欢的话别忘了给本库一个Star😊).

想加密数据库的,请借鉴此demo:SQLCipherDemo

CocoaPods的方式.

Podfile

platform :ios, '8.0'

target '工程名称' do
pod 'BGFMDB', '~> 2.0.9'
end

直接下载库代码使用方式.

添加所需依赖库

libsqlite3

导入头文件

/**
只要在自己的类中导入了BGFMDB.h这个头文件,本类就具有了存储功能.
*/
#import <Foundation/Foundation.h>
#import "BGFMDB.h"
@interface stockModel : NSObject
@property(nonatomic,copy)NSString* name;
@property(nonatomic,strong)NSNumber* stockData;
+(instancetype)stockWithName:(NSString*)name stockData:(NSNumber*)stockData;
@end

主键

/**
本库自带的自动增长主键.
*/
@property(nonatomic,strong)NSNumber*_Nullable bg_id;

/**
 为了方便开发者,特此加入以下两个字段属性供开发者做参考.(自动记录数据的存入时间和更新时间)
 */
@property(nonatomic,copy)NSString* _Nonnull bg_createTime;//数据创建时间(即存入数据库的时间)
@property(nonatomic,copy)NSString* _Nonnull bg_updateTime;//数据最后那次更新的时间.

/**
 自定义表名
 */
@property(nonatomic,copy)NSString* _Nonnull bg_tableName;

联合主键

/**
 自定义“联合主键” ,这里指定 name和age 为“联合主键”.
 */
+(NSArray *)bg_unionPrimaryKeys{
    return @[@"name",@"age"];
}

唯一约束

/**
 如果需要指定“唯一约束”字段, 在模型.m文件中实现该函数,这里指定 name和age 为“唯一约束”.
 */
+(NSArray *)bg_uniqueKeys{
    return @[@"name",@"age"];
}

设置不需要存储的属性

/**
 设置不需要存储的属性, 在模型.m文件中实现该函数.
 */
+(NSArray *)bg_ignoreKeys{
   return @[@"eye",@"sex",@"num"];
}

初始化对象

People* p = [self people];

存储

/**
同步存储.
*/
[p bg_save];

/**
异步存储.
*/
[p bg_saveAsync:^(BOOL isSuccess) {
       //you code
   }];
   
/**
覆盖掉原来People类的所有数据,只存储当前对象的数据.
*/
[p bg_cover];

/**
 同步存储或更新.
 当"唯一约束"或"主键"存在时,此接口会更新旧数据,没有则存储新数据.
 提示:“唯一约束”优先级高于"主键".
 */
 [p bg_saveOrUpdate];
 
/**
同步 存储或更新 数组元素.
当"唯一约束"或"主键"存在时,此接口会更新旧数据,没有则存储新数据.
提示:“唯一约束”优先级高于"主键".
*/
[People bg_saveOrUpdateArray:@[p,p1,p2]];

查询

/**
同步查询所有数据.
*/
NSArray* finfAlls = [People bg_findAll:bg_tablename];

/**
按条件查询.
*/
NSString* where = [NSString stringWithFormat:@"where %@=%@",bg_sqlKey(@"name"),bg_sqlValue(@"斯巴达")];
NSArray* arr = [People bg_find:bg_tablename where:where];

/**
 直接写SQL语句操作.
 */
NSArray* arr = bg_executeSql(@"select * from yy", bg_tablename, [People class]);//查询时,后面两个参数必须要传入.

/**
 根据范围查询.
*/
NSArray* arr = [People bg_find:bg_tablename range:NSMakeRange(i,50) orderBy:nil desc:NO];

更新

/**
 单个对象更新.
 支持keyPath.
 */
 NSString* where = [NSString stringWithFormat:@"where %@ or %@=%@",bg_keyPathValues(@[@"user.student.human.body",bg_equal,@"小芳"]),bg_sqlKey(@"age"),bg_sqlValue(@(31))];
  [p bg_updateWhere:where];
  
/**
 sql语句批量更新.
 */
  NSString* where = [NSString stringWithFormat:@"set %@=%@ where %@=%@",bg_sqlKey(@"name"),bg_sqlValue(@"马化腾"),bg_sqlKey(@"name"),bg_sqlValue(@"天朝")];
  [People bg_update:bg_tablename where:where];  
  
/**
 直接写SQL语句操作
 */
bg_executeSql(@"update yy set BG_name='标哥'", nil, nil);//更新或删除等操作时,后两个参数不必传入.

删除

/**
 按条件删除.
 */
NSString* where = [NSString stringWithFormat:@"where %@=%@",bg_sqlKey(@"name"),bg_sqlValue(@"斯巴达")];
[People bg_delete:bg_tablename where:where];

/**
清除表的所有数据.
*/
[People bg_clear:bg_tablename];

/**
删除数据库表.
*/
[People bg_drop:bg_tablename];

获取类数据库版本

/**
 获取该类的数据库版本号;
*/
NSInteger version = [People bg_version:bg_tablename];

类数据库版本手动升级(当'唯一约束','联合主键','属性类型改变',发生改变时需要手动调用升级,其他情况库自动检测升级)

//注: 版本号从1开始,依次往后递增,本次更新版本号不得 低于或等于 上次的版本号,否则不会更新.
/**
 如果类'唯一约束','联合主键','属性类型'发生改变.
 则调用此API刷新该类数据库,不需要新旧映射的情况下使用此API.
*/
[People bg_update:bg_tablename version:version];

/**
如果类'唯一约束','联合主键','属性类型'发生改变.
则调用此API刷新该类数据库.data2是新变量名,data是旧变量名,即将旧的值映射到新的变量名,其他不变的变量名会自动复制,只管写出变化的对应映射即可.
*/
[People bg_update:bg_tablename version:version keyDict:@{@"data2":@"data"}];

事务操作

/**
事务操作,返回YES提交事务,返回NO则回滚事务.
*/
bg_inTransaction(^BOOL{
        [p bg_save];//存储
        return NO;
    });

快速查询数据条数

/**
按条件查询表中所有数据的条数.
*/
NSInteger count = [People bg_count:bg_tablename where:nil];

类数据之间的拷贝

/**
 将People表的数据拷贝给bg_tablename表, name拷贝给Man的Man_name,其他同理.
 */
 [People bg_copy:nil toTable:bg_tablename keyDict:@{@"name":@"Man_name",
                                                       @"num":@"Man_num",
                                                       @"age":@"Man_age",
                                                       @"image":@"image"} append:NO];

直接存取数组

NSMutableArray* testA = [NSMutableArray array];
    [testA addObject:@"我是"];
    [testA addObject:@(10)];
    [testA addObject:@(9.999)];
    [testA addObject:@{@"key":@"value"}];
    /**
     存储标识名为testA的数组.
     */
    [testA bg_saveArrayWithName:@"testA"];
    
    /**
     往标识名为@"testA"的数组中添加元素.
     */
    [NSArray bg_addObjectWithName:@"testA" object:@[@(1),@"哈哈"]];
    
    /**
     删除标识名为testA的数组某个位置上的元素.
     */
    [NSArray bg_deleteObjectWithName:@"testA" Index:3];
    
    /**
     查询标识名为testA的数组全部元素.
     */
    NSArray* testResult = [NSArray bg_arrayWithName:@"testA"];
    
    /**
     获取标识名为testA的数组某个位置上的元素.
     */
    id arrObject = [NSArray bg_objectWithName:@"testA" Index:3];
    
    /**
     清除标识名为testA的数组所有元素.
     */
    [NSArray bg_clearArrayWithName:@"testA"];

直接存取字典

NSDictionary* dict = @{@"one":@(1),@"key":@"value",@"array":@[@(1.2),@"哈哈"]};
    /**
     存储字典.
     */
    [dict bg_saveDictionary];
    
    /**
     添加字典元素.
     */
    [NSDictionary bg_setValue:@"标哥" forKey:@"name"];
    
    /**
     获取某个字典元素.
     */
    id num = [NSDictionary bg_valueForKey:@"one"];
    
    /**
     移除字典某个元素.
     */
    [NSDictionary bg_removeValueForKey:@"key"];
    
    /**
     遍历字典元素.
     */
    [NSDictionary bg_enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, id  _Nonnull value, BOOL *stop) {
        NSLog(@"key = %@ , value = %@",key,value);
    }];
    
    /**
     清空字典.
     */
    [NSDictionary bg_clearDictionary];

注册数据变化监听

/**
注册监听bg_tablename表的数据变化,唯一识别标识是@"change".  
*/
[People bg_registerChangeForTableName:bg_tablename identify:@"change" block:^(bg_changeState result) {
        switch (result) {
            case bg_insert:
                NSLog(@"有数据插入");
                break;
            case bg_update:
                NSLog(@"有数据更新");
                break;
            case bg_delete:
                NSLog(@"有数据删删除");
                break;
            case bg_drop:
                NSLog(@"有表删除");
                break;
            default:
                break;
        }
    }];

移除数据监听

/**
移除bg_tablename表数据变化的监听,唯一识别标识是@"change".  
*/
 [People bg_removeChangeForTableName:bg_tablename identify:@"change"];

字典转模型

NSDictionary* dictAni = [self getDogDict];
/**
一代码搞定字典转模型.
*/
Dog* dog = [Dog bg_objectWithKeyValues:dictAni];

NSDictionary* dictMy = [self getMyDict];
/**
一代码搞定字典转模型.
*/
My* my = [My bg_objectWithDictionary:dictMy];

模型转字典

/**
一句代码搞定模型转字典.
*/
 NSDictionary* dictBodyAll = [body bg_keyValuesIgnoredKeys:nil];
 
/**
忽略掉hand这个变量不转.
*/
NSDictionary* dictBody = [body bg_keyValuesIgnoredKeys:@[@"hand"]];

如果模型中的数组变量存储的是自定义类,则需要实现下面的这个函数:

/**
如果模型中有数组且存放的是自定义的类(NSString等系统自带的类型就不必要了),那就实现该函数,key是数组名称,value是自定的类Class,用法跟MJExtension一样.
(‘字典转模型’ 或 ’模型转字典‘ 都需要实现该函数)
*/
+(NSDictionary *)bg_objectClassInArray{
    return @{@"dogs":[Dog class],@"bodys":[Body class]};
}

/**
 如果模型中有自定义类变量,则实现该函数对应进行集合到模型的转换.
 将json数据中body这个key对应的值转化为Body类变量body对象.
 */
+(NSDictionary *)bg_objectClassForCustom{
    return @{@"body":[Body class]};
}

/**
 替换变量的功能(及当字典的key和属性名不一样时,进行映射对应起来)
 即将字典里key为descri的值 赋给 属性名为intro的变量,性别和sex同理.
 */
+(NSDictionary *)bg_replacedKeyFromPropertyName{
    return @{@"descri":@"intro",@"性别":@"sex"};
}

更多功能请下载demo运行了解使用.