SmileZXLee / ZXDataHandle

简单易用的数据转换和存储框架,支持一行代码将模型、模型数组、Json字符串、字典互转;支持模型映射到sqlite3数据库,无需书写sql
MIT License
15 stars 2 forks source link
dictionary json model sqlite3 store

ZXDataHandle使用方法

License MIT  CocoaPods  CocoaPods  Support 

安装

通过CocoaPods安装

pod 'ZXDataHandle'

手动导入

导入头文件

#import "ZXDataHandle.h"

数据转换-ZXDataConvert

注:浮点数精度问题内部已自动处理(建议Model中使用NSString接收)

概要:使用方法三句话就可以概括:

a.有东西要转模型,调用模型类的+zx_modelWithObj:方法,并把这个东西传给它即可。
b.有东西要转字典,调用它的-zx_toDic方法即可。
c.有东西要转Json字符串,调用它的-zx_toJsonStr方法即可。

下面是详细的例子:

1. 字典、字典数组、Json字符串或NSData -> 模型:

[Class zx_modelWithObj:obj];

例:[Bird zx_modelWithObj:dic];
注:Class为目标模型类,obj可以是单一字典、字典数组、Json字符串或NSData。

2. 模型、模型数组、Json字符串或NSData -> 字典

[obj zx_toDic];

例:[bird zx_toDic]; 注:obj可以是单一模型、模型数组、Json字符串或NSData

3. 字典、字典数组、模型、模型数组或NSData -> Json 字符串

[obj zx_toJsonStr];

例:[bird zx_toJsonStr]; 注:obj可以是字典,字典数组,模型、模型数组或NSData

4. 数据转换特殊情况

注2:属性替换1和属性替换2都涉及属性的替换操作,当二者发生冲突时,属性替换1的方法优先级高于属性替换2,也就是说,属性替换1中(+zx_replaceProName)修改的属性,在属性替换2中(+zx_replaceProName121)不会被修改。

5. 在字典转模型model赋值前对其进行修改,可以在AppDelegate的didFinishLaunchingWithOptions直接书写以下代码

[ZXDataConvert shareInstance].zx_dataConvertSetterBlock = ^id _Nonnull(NSString * _Nonnull key, id  _Nonnull orgValue, id owner) {
    //key:属性名
    //orgValue:属性名对应的即将被赋值的Value
    //owner:属性所属的对象
    //如果给模型赋值的是NSNumer类型,则一律转为NSString类型
    if([orgValue isKindOfClass:[NSNumber class]]){
            return [NSString stringWithFormat:@"%@",orgValue];
    }
    return orgValue;
};

6. 自动类型转换

若Model中对应属性接收类型与json中属性类型不一致,ZXDataHandle会自动进行类型转换,规则如下

数据存储-ZXDataStore

  1. 文件,数据直接存储
    • 用户偏好存储与读取(无法直接对自定义类进行操作)
//存储用户偏好数据
//注意 如果saveObj的对象为自定义对象,则ZXDataStoreCache会将其转为字典再存储
[ZXDataStoreCache saveObj:@"123" forKey:@"pwd"];
//读取用户偏好数据
id data = [ZXDataStoreCache readObjForKey:@"123"];

```objective-c
//数据归档,将数据存储至当前沙盒document目录下,文件名为apple
Apple *apple = [[Apple alloc]init];
apple.name = @"嘻哈苹果";
//将apple对象存储到document文件夹中,名为apple
[ZXDataStoreCache arcObj:apple pathComponent:@"apple"];
//支持多级存储,以下写法将自动创建文件夹并存储,下方代码会自动创建test1文件夹,并在test1文件夹中创建test2文件夹,并将apple对象存储到test2中
//[ZXDataStoreCache arcObj:apple pathComponent:@"test1/test2/apple"];
//数据读档,将数据从当前沙盒document/apple目录下读取出来
Apple *apple = [[Apple alloc]init];
apple.name = @"嘻哈苹果";
id data = [ZXDataStoreCache unArcObjPathComponent:@"apple"];
//arcObj传nil即为删除,若pathComponent路径对应是一个文件,则删除此文件,若为文件夹,则删除此文件夹以及其中所有内容,包括子文件夹与子文件
[ZXDataStoreCache arcObj:nil pathComponent:@"test1/test2/apple"];
//创建一个对象
Apple *apple = [[Apple alloc]init];
apple.name = @"嘻哈苹果";
apple.dec = @"很好吃哦";
apple.soldMoney = 100;

//保存
BOOL res = [apple zx_dbSave];
NSLog("操作结果-%i",res);

注:您只需创建一个需要存储的对象,调用其-zx_dbSave方法即可,ZXDataStore会自动为当前项目创建一个数据库,并根据对象的属性创建同名的表,同时将数据插入到表中。

//创建一个对象数组
NSMutableArray *appleArr = [NSMutableArray array];
for (NSUInteger i = 0; i < 10; i++) {
    Apple *apple = [[Apple alloc]init];
    apple.name = @"嘻哈苹果";
    apple.dec = @"很好吃哦";
    apple.soldMoney = 100 + i;
    [appleArr addObject:apple];
}

//保存
BOOL res = [appleArr zx_dbSave];
NSLog("操作结果-%i",res);

注:调用对象数组的-zx_dbSave即可批量存储数据,ZXDataStore进行了数据库事务优化,加快存储速度。

以下操作等同于SQL语句:DELETE FROM Apple WHERE soldMoney = 100

//zx_dbDropWhere:可以传入一个字典,where语句多个键值对之间默认使用AND连接,键值之间使用等号连接,其他情况请使用以下两种

BOOL res = [Apple zx_dbDropWhere:@{@"soldMoney":@"100"}];
NSLog("操作结果-%i",res);

//zx_dbDropWhere:可以传入一段where语句,以及where之后的运算符

BOOL res = [Apple zx_dbDropWhere:@"id=100"];
NSLog("操作结果-%i",res);

//zx_dbDropWhereArg:可以传入多个参数,多个参数拼接成where语句,以及where之后的运算符

BOOL res = [Apple zx_dbDropWhereArg:@"id=",@"100"];
NSLog("操作结果-%i",res);
//创建一个更新之后的对象,若对象属性未赋值,则对应字段不会被修改
Apple *apple = [[Apple alloc]init];
apple.name = @"坏掉的苹果";
apple.dec = @"不好吃哦";
apple.soldMoney = 10;

//将Apple表中name等于“嘻哈苹果”的数据的name值改为“坏掉的苹果”,dec改为“不好吃哦”,soldMoney改为10
BOOL res = [apple zx_dbUpdateWhere:@"name='嘻哈苹果'"];
NSLog("操作结果-%i",res);
//查询Apple表中soldMoney大于等于100的所有数据
NSArray *resArr = [Apple zx_dbQuaryWhere:@"soldMoney >= 100"];

//resArr即为查询结果数组,resArr中是Apple对象
NSLog(@"resArr--%@",resArr);

Ⅰ.where语句后面可以有多种运算符表示方式,如WHERE NAME LIKE 'ap%',您可以使用where或whereArg拼接所需参数。

Ⅱ.您可以通过对象或字典来更新数据,以下是范例。

通过自定义对象更新数据

NSNumber *updateSoldMoney = @104;
Apple *updateApp = [[Apple alloc]init];
updateApp.dec = @"这是通过自定义对象更新的数据测试";
BOOL res  = [updateApp zx_dbUpdateWhereArg:@"soldMoney=",updateSoldMoney,nil];
NSLog(@"结果--%i",res);

通过字典更新数据

NSNumber *updateSoldMoney = @104;
NSDictionary *updateDic = @{@"dec":@"这是通过字典更新的数据测试",@"soldMoney":@"+=66",@"testAdd":@"测试的后来新增的字段"};
BOOL res = [Apple zx_dbUpdateDic:updateDic whereArg:@"soldMoney=",updateSoldMoney,nil];
NSLog(@"结果--%i",res);

注:通过自定义对象更新数据有一些弊端,此次需要说明:
a.假如您需要通过自定义对象把表中的例如soldMoney置为0是无法做到的,因为ZXSQliteHandle无法获知soldMoney=0是对象本身初始化时候就为0还是您设置成0的,当然有很多方法可以添加设置,但是考虑到操作简便性和易用性统一规定对象中数值类型的0不纳入update范围。
b.您无法进行对应字段自增自减,字段赋值等操作。

通过字典来更新数据可以解决这些弊端,依据您的具体需求和习惯而定,下面是一些例子:

//将soldMoney的值在原本基础上加66
NSDictionary *updateDic = @{@"soldMoney":@"+=66"};
//另一种写法
NSDictionary *updateDic2 = @{@"soldMoney":@"soldMoney+66"};
//将dec的值赋值给name
NSDictionary *updateDic = @{@"name":@"dec"};

Ⅲ.关于数据库表的修改问题

在实际开发中存在例如后期增加需求,对应的数据库表的模型需要增加字段,修改字段,删除字段的情况,由于数据库表的建立只是第一次不存在表的时候创建,因此此时需要考虑数据库表的修改。

Sqlite3操作仅允许对表进行更改表名,增加列的操作,我们可以通过备份表,重新进行表设计和数据赋值达到“修改表字段”或“删除表字段”的目的,但是在ZXSQliteHandle设计的时候考虑到具体的开发需求一般是增加字段,以及具体的效率等等原因,综合考虑仅自动进行数据库表的自动增加字段操作。

若您在数据库表的模型中增加了一个属性(NSString或数值类型),在您进行数据存储或更新操作时,ZXSQliteHandle会自动为表新增一个对应类型的属性并继续执行存储或更新操作,您无需进行任何额外处理。

Ⅳ.其他 ZXSQliteHandle默认为您当前项目创建一个您当前项目的BundleId.sqlite的数据库,数据库中的表名与对应对象一一对应,主键名为id且自增,您无需关心数据库如何创建,表如何设计,SQL语句如何写,但是如此也必然有弊端,ZXSQliteHandle可以满足绝大部分需求,但诸如外键,多表关联等等不常用的功能需要您额外处理。考虑到易用性等方面,ZXSQliteHandle仅提供核心的数据库处理,还望谅解。

任何问题欢迎随时issue我