Giter VIP home page Giter VIP logo

coremodel's Introduction

image

不需要懂sql,一键数据库存储工具(成都时点软件开发有限公司原创出品)

列表终结者框架即将开源:一键实现一个列表,含有上拉下拉与分页,全自动数据解析,加载视图,动态缓存。




一、CoreModel使用前言


#### 1.为什么要重制? 在推出了CoreModel感谢大量朋友对我的框架的喜欢,同时也提出了各种问题和要求,最重要的有以下:
> (1). 不支持NSData。
> (2). 不支持NSArray。
> (3). 全部主线程操作,对性能有一定的影响。

#### 1.本次更新了什么新特性? > (1). Reflect全面抛弃MJExtension,此框架在CoreModel中有大量崩溃。目前框架全面原创,自有Reflect,从此CoreModel再无崩溃。
> (2). 无hostID可以全自动创建。不会再触发断言。不过不建议无hostID的数据插入,可能会造成大量重复数据。

注: 有很多朋友提到hostID需要字符串化,因为有的服务器的id是一个特别的字符串,现在你可以把这个类似id的字符串存为一个普通字段,然后无hostID存入即可。后面CURD直接根据此字段来关联操作即可。


#### 3.框架依赖 > (1). CoreFMDB 数据库操作。

#### 3.其他说明(持续关注[信息公告牌](https://github.com/CharlinFeng/Show)) > (1). 强烈建议关注:`信息公告牌`以便获取最实时的框架更新动态。
> (2). 开源第四季一键列表的条件为:`CoreModel的Star数据超过1000`。
> (3). 之前有朋友过于喜欢我的框架,导致在没有任何说明的情况下借用我的代码,所以本次框架去除了所有的中文注释。从使用的角度上来说对您没有任何影响。
> (4). 请添加异常断点,以便捕获我提供的大量断言。
> (5). 特别提醒:示例程序有强烈的先后顺序,最好不要随便乱点,比如一个数据都没有insert,你点击了update或者delete等操作会达到你难以理解的结果。

#### 4.最终申明 在开始之前,请您注意以下几点:
>(1). 导入了sqlite3.lib 动态库。
>(2). 拖拽CoreModel及FrameWorks文件夹到您的项目。
>(3). 安装了Navicat Preminum。
>(4). Swift使用,不能Swift中的Model继承CoreModel。




二、基本使用


####新建模型Person,继承自CoreModel,模型加入以下属性:
#import "CoreModel.h"

@interface Person : CoreModel

@property (nonatomic,copy) NSString *name;

@property (nonatomic,assign) NSInteger age;

@end




三、全自动创表


#### 框架全自动创表触发的条件:调用CoreModel子类的任意一个方法。 ##### 本功能请参考项目中:Test2VC.m 现在,我们随意调用Person的任意一个方法,这里我们以实例化一个Person实例说明:
/** 全自动创表 */
Person *person = [[Person alloc] init];

,查看控制台输出,已经发现成功创建了数据库,成功创建表,并写入了字段信息:

    sqlite> PRAGMA table_info (Person);
    +------+--------+---------+---------+------------+------+
    | cid  | name   | type    | notnull | dflt_value | pk   |
    +------+--------+---------+---------+------------+------+
    | 0    | id     | INTEGER | 1       | 0          | 1    |
    | 1    | name   | TEXT    | 1       | ''         | 0    |
    | 2    | age    | INTEGER | 1       | 0          | 0    |
    | 3    | hostID | INTEGER | 1       | 0          | 0    |
    | 4    | pModel | TEXT    | 1       | ''         | 0    |
    | 5    | pid    | INTEGER | 1       | 0          | 0    |
    +------+--------+---------+---------+------------+------+
    6 rows in set (0.02 sec)

说明:

(1). 框架在控制台输出的第一条信息就是您的DB位置:dbPath:path.sql,请注意因为iOS沙盒机制有变化,这个Path会不停的变化,你使用Navicat Preminum查看数据库文件的时候,最好是每次都更新path(在数据库连接上右键,修改当前DB的path)。
(2). 有您不熟悉的字段如pid,pModel是框架辅助字段,请不要删除。
(3). 核心字段:hostID是服务器主键,任何使用CoreModel的模型必须拥有唯一的hostID,如果您没有hostID,请构建。




四、调试模式与非调试模式


#### 框架有极其全面的Debug信息与断言帮助您正确的使用CoreModel ##### 如果您不喜欢控制台大量输出Debug信息,请到CoreModelConst.h文件,修改以下宏定义:
/** Debug */
#define CoreModelDeBug 1

,如果您修改为1,即是Debug模式,控制台会有大量输出,如果您不需要显示,改为0即可。




五、全部子线程运行 + Block回调,性能卓越!


#### 我们还是打开Debug模式,请查看控制台各种关于线程的输入.
##### 不仅仅是创建是这样,后面所有关于数据库的CURD操作,全部是在子线程中完成的,基本Operation,同时有并发限制,多线程在本框架得到完美展现,性能不再是问题!
2015-09-09 10:58:44.291 CoreModel[3427:3903] dbPath:/Users/Charlin/Library/Developer/CoreSimulator/Devices/E1B1C2D8-DC98-4571-AF45-8A6D76F07497/data/Applications/9174CFF6-3EA1-4BDB-904C-C5373E0E00E0/Documents/CoreModel/CoreModel.sql
2015-09-09 10:58:44.293 CoreModel[3427:3903] 表创建完毕<NSThread: 0x7a679c80>{name = (null), num = 2}
2015-09-09 10:58:44.293 CoreModel[3427:3903] 字段检查所在线程:<NSThread: 0x7a679c80>{name = (null), num = 2}
2015-09-09 10:58:44.294 CoreModel[3427:3903] 字段也检查完毕<NSThread: 0x7a679c80>{name = (null), num = 2}
2015-09-09 10:58:44.294 CoreModel[3427:3903] 创表所在线程:<NSThread: 0x7a679c80>{name = (null), num = 2}

注意:因为是子线程,所以您的block回调,全部是子线程,如果你在block里面更新UI,或者Push界面,需要自行回到主线程。你可能会问我的block为什么不在主线程中回调,因为有的时候block回调需要可能还有一定的数据处理,在主线程中执行同样会有一定的性能浪费。这一点在第四季和第五季中有强烈的展现。所以,决定权交给您自己。




五、模型字段检查,全自动增加字段


有时候你可能有这样的需求,开发到一定阶段或者版本,需要增加模型字段。CoreModel已经完全为您考虑了这种情况,下面我们修改Person模型,增加一个Height字段,结果如下:
@interface Person : CoreModel

@property (nonatomic,copy) NSString *name;

@property (nonatomic,assign) NSInteger age;

@property (nonatomic,assign) CGFloat height;

@end

,此时我们再向Person发送任意消息,并查看控制台输出:

2015-09-09 11:06:47.269 CoreModel[3474:3903] 注意:模型 Person 有新增加的字段 height,已经实时添加到数据库中!

,我们打开数据库查看表结构:

sqlite> PRAGMA table_info (Person);
+------+--------+---------+---------+------------+------+
| cid  | name   | type    | notnull | dflt_value | pk   |
+------+--------+---------+---------+------------+------+
| 0    | id     | INTEGER | 1       | 0          | 1    |
| 1    | name   | TEXT    | 1       | ''         | 0    |
| 2    | age    | INTEGER | 1       | 0          | 0    |
| 3    | hostID | INTEGER | 1       | 0          | 0    |
| 4    | pModel | TEXT    | 1       | ''         | 0    |
| 5    | pid    | INTEGER | 1       | 0          | 0    |
| 6    | height | REAL    | 1       | 0.0        | 0    |
+------+--------+---------+---------+------------+------+
7 rows in set (0.04 sec)

我们发现,字段已经成功增加。

你可能会问,如果我想删除一个属性,框架会自动删除字段吗?答案是否定的,原因有以下:

(1). 如果删除字段,之前的有关此字段的数据全部丢失,如果你后期又想使用此字段,就造成了遗憾。
(2). Sqlite 3本身无删除字段语法,有技术可以实现,但对有大量数据的表来说有极大的操作风险。




五、无hostID操作


##### 本功能请参考项目中:Test3VC.m #### 为了让您正确的使用CoreModel,框架做了大量的断言帮助您正确的使用,最容易出现的错误就是对HostID认识不够深刻,假如您的模型没有设置HostID,现在框架会自动创建hostID,请一定要注意这种情况下可能会有重复数据出现。

此外,以下不合法操作均会触发断言:

(1). 模型混用,比如使用Cat类方法对Person执行数据操作如[Cat insert:person resBlock:nil];
(2). 数组支持中,数组申明OC数组成员为NSInteger、CGFloat、Bool等(后面会有详细介绍)。

注意:

(1). HostID是对应服务器表的主键,在CoreModel中hostID会自动映射解析服务器json里面的id字段,你无需手动映射。




六、基本模型 + 单条数据插入


我们构建合法的Person对象,并执行Insert操作:

本功能请参考项目中:Test4VC.m
Person *person = [[Person alloc] init];
person.hostID = 1;
person.name = @"冯成林";
person.age = 28;
person.height = 174.0;
/** Insert */
[Person insert:person resBlock:^(BOOL res) {
    [self show:res];
}];

,运行结果提示成功,并且控制台输出全部是在子线程中完成,我们查看数据库:

sqlite> select * from Person;
+----+-----------+-----+--------+--------+-----+--------+
| id | name      | age | hostID | pModel | pid | height |
+----+-----------+-----+--------+--------+-----+--------+
| 1  | 冯成林    | 28  | 1      |        | 0   | 174.0  |
+----+-----------+-----+--------+--------+-----+--------+
1 rows in set (0.05 sec)
注: 当你再次运行Test4VC.m,会发现提示失败,那是因为hostID为1的数据已经存在,
错误:Person表中hostID=1的数据记录已经存在!

你也可以通过查看控制台,能够看到上面的Debug输出,明白这是合理的。




七、基本模型 + 批量数据插入


##### 本功能请参考项目中:Test5VC.m
Person *p1 = [[Person alloc] init];
p1.hostID = 2;
p1.name = @"jack";
p1.age = 25;
p1.height = 180;

Person *p2 = [[Person alloc] init];
p2.hostID = 3;
p2.name = @"jim";
p2.age = 22;
p2.height = 172;


[Person inserts:@[p1,p2] resBlock:^(BOOL res) {
    [self show:res];
}];

提示成功,数据库返回结果如下:

sqlite> select * from Person;
+----+-----------+-----+--------+--------+--------+-----+
| id | name      | age | height | hostID | pModel | pid |
+----+-----------+-----+--------+--------+--------+-----+
| 1  | 冯成林    | 28  | 174.0  | 1      |        | 0   |
| 2  | jack      | 25  | 180.0  | 2      |        | 0   |
| 3  | jim       | 22  | 172.0  | 3      |        | 0   |
+----+-----------+-----+--------+--------+--------+-----+
3 rows in set (0.01 sec)




八、基本模型 + 单条数据修改


##### 本功能请参考项目中:Test6VC.m ##### 这里我修改了我的姓名和身高字段值,请注意前后对比:
Person *person = [[Person alloc] init];
person.hostID = 1;
person.name = @"Charlin Feng";
person.age = 28;
person.height = 173.5;
[Person update:person resBlock:^(BOOL res) {
    [self show:res];
}];

执行结果:

sqlite> select * from Person;
+----+--------------+-----+--------+--------+--------+-----+
| id | name         | age | height | hostID | pModel | pid |
+----+--------------+-----+--------+--------+--------+-----+
| 1  | Charlin Feng | 28  | 173.5  | 1      |        | 0   |
| 2  | jack         | 25  | 180.0  | 2      |        | 0   |
| 3  | jim          | 22  | 172.0  | 3      |        | 0   |
+----+--------------+-----+--------+--------+--------+-----+
3 rows in set (0.01 sec)




九、基本模型 + 批量数据修改


##### 本功能请参考项目中:Test7VC.m ##### 这里我修改了姓名字段值,请注意前后对比:
Person *p1 = [[Person alloc] init];
p1.hostID = 2;
p1.name = @"杰克";
p1.age = 25;
p1.height = 180;
Person *p2 = [[Person alloc] init];
p2.hostID = 3;
p2.name = @"吉姆";
p2.age = 22;
p2.height = 172;
[Person updateModels:@[p1,p2] resBlock:^(BOOL res) {
    [self show:res];
}];

执行结果:

sqlite> select * from Person;
+----+--------------+-----+--------+--------+--------+-----+
| id | name         | age | height | hostID | pModel | pid |
+----+--------------+-----+--------+--------+--------+-----+
| 1  | Charlin Feng | 28  | 173.5  | 1      |        | 0   |
| 2  | 杰克         | 25  | 180.0  | 2      |        | 0   |
| 3  | 吉姆         | 22  | 172.0  | 3      |        | 0   |
+----+--------------+-----+--------+--------+--------+-----+
3 rows in set (0.01 sec)




十、基本模型 + 单条数据保存


##### 本功能请参考项目中:Test8VC.m #### 请注意数据保存(Save) 和数据插入(Insert)是有区别的 ##### Insert是简单的数据插入,如果数据存在要么抛出错误,要不返回不处理 ##### Save是指保存数据时,进行智能判断,如果数据记录不存在,执行Insert操作。如果数据已经存在,执行Update操作,总之,执行Save操作后,你指定的数据一定会作为最新数据记录在数据库中。

模型数据:修改了名称与年龄,请注意前后比对:

Person *p1 = [[Person alloc] init];
p1.hostID = 2;
p1.name = @"杰克先生";
p1.age = 40;
p1.height = 180;
Person *p2 = [[Person alloc] init];
p2.hostID = 3;
p2.name = @"吉姆先生";
p2.age = 38;
p2.height = 172;
[Person saveModels:@[p1,p2] resBlock:^(BOOL res) {
    [self show:res];
}];

执行结果:

sqlite> select * from Person;
+----+--------------+-----+--------+--------+--------+-----+
| id | name         | age | height | hostID | pModel | pid |
+----+--------------+-----+--------+--------+--------+-----+
| 1  | Charlin Feng | 28  | 173.5  | 1      |        | 0   |
| 2  | 杰克先生     | 40  | 180.0  | 2      |        | 0   |
| 3  | 吉姆先生     | 38  | 172.0  | 3      |        | 0   |
+----+--------------+-----+--------+--------+--------+-----+
3 rows in set (0.01 sec)

注意: > (1). 如果是单条数据保存,请使用 `+(void)save:(id)model resBlock:(void(^)(BOOL res))resBlock;`
> (2). 如果是批量数据保存,请使用 `+(void)saveModels:(NSArray *)models resBlock:(void(^)(BOOL res))resBlock`
> (3). 有一种情况比较特殊,就是你不清楚是单条还是批量(CoreModel内部有遇到此种情况并使用了此方法),请使用 `+(void)saveDirect:(id)obj resBlock:(void(^)(BOOL res))resBlock`
> (4). 再次提醒,此方法会导致数据一定写入数据库,和insert与update有区别,请知晓。




十一、基本模型 + 条件删除


##### 本功能请参考项目中:Test9VC.m ##### 我们删除年龄大于等于40岁的记录:
[Person deleteWhere:@"age >= 40" resBlock:^(BOOL res) {
    [self show:res];
}];

执行结果,杰克先生因为年龄刚好40岁,所以被删除:

sqlite> select * from Person;
+----+--------------+-----+--------+--------+--------+-----+
| id | name         | age | height | hostID | pModel | pid |
+----+--------------+-----+--------+--------+--------+-----+
| 1  | Charlin Feng | 28  | 173.5  | 1      |        | 0   |
| 3  | 吉姆先生     | 38  | 172.0  | 3      |        | 0   |
+----+--------------+-----+--------+--------+--------+-----+
2 rows in set (0.02 sec)

说明:您还可以根据主键一键删除,注意主键指的是hostID,而非本地数据库的主键id。




十二、基本模型 + 条件查询


##### 本功能请参考项目中:Test10VC.m ##### 为了更好的检验数据查询是否成功,CoreModel增加了description方法,直接打印即可。
[Person selectWhere:nil groupBy:nil orderBy:nil limit:nil selectResultsBlock:^(NSArray *selectResults) {
    
    NSLog(@"%@",selectResults);
}];

执行结果,

2015-09-09 14:52:18.806 CoreModel[5335:3a03] (
    "[Person]<0x7c199670>: 
      name: Charlin Feng, 
      age: 28, 
      height: 173.5, 
      hostID: 1, 
      pModel: , 
      pid: 0, 
",
    "[Person]<0x7c19a330>: 
      name: \U5409\U59c6\U5148\U751f, 
      age: 38, 
      height: 172, 
      hostID: 3, 
      pModel: , 
      pid: 0, 
"
)

请注意:

(1). 因为我们刚刚测试了删除,删除了一条记录,所以现在结果当然是两条。
(2). 框架对CoreModel做了desctiontion自动处理,您能直接看到以上结果。
(3). 和删除类似,您也可以根据hostID(再次提示,非本地数据库id)快速查找一条记录,使用的方法为:+(void)find:(NSUInteger)hostID selectResultBlock:(void(^)(id selectResult))selectResultBlock;




十三、基本模型 + 清空表数据


##### 本功能请参考项目中:Test11VC.m
[Person truncateTable:^(BOOL res) {
}];

注意:清空了所有表记录,同时重置了本地数据库的主键id,慎用!




十四、NSData的支持


##### 本功能请参考项目中:Test12VC.m 框架新增加对NSData的支持,我们需要给Person模型增加一个NSData的属性(当然框架会自动新增字段):
@interface Person : CoreModel

@property (nonatomic,copy) NSString *name;

@property (nonatomic,assign) NSInteger age;

@property (nonatomic,assign) CGFloat height;

@property (nonatomic,strong) NSData *photoData;

@end

我们直接使用最普通的方式保存,

Person *charlin = [[Person alloc] init];
charlin.hostID = 1;
charlin.name = @"冯成林";
charlin.age = 28;
charlin.photoData = UIImagePNGRepresentation([UIImage imageNamed:@"1"]);
[Person save:charlin resBlock:^(BOOL res) {
    [self show:res];
}];

,然后我们查询数据即可,请注意回调全部是子线程,更新UI请回到主线程:

__weak typeof(self) weakSelf=self;
[Person find:1 selectResultBlock:^(Person *selectResult) {
    
    [weakSelf show:selectResult != nil];
    
    dispatch_async(dispatch_get_main_queue(), ^{
        
        weakSelf.imageV.image = [[UIImage alloc] initWithData:selectResult.photoData];
        
        weakSelf.label.text = [NSString stringWithFormat:@"%@%@",selectResult.name,@(selectResult.age)];
    });
    
}];




十五、属性为单模型级联:数据插入(级联模型请一定要全部是CoreModel的子类!)


##### 本功能请参考项目中:Test13VC.m ##### 首先解释标题意思:指的是模型有一个属性是自定义模型,为了演示效果,我们再定义一个City类,且Person有一个属性是城市。
这个是目前的Person模型:
@interface Person : CoreModel

@property (nonatomic,copy) NSString *name;

@property (nonatomic,assign) NSInteger age;

@property (nonatomic,assign) CGFloat height;

@property (nonatomic,strong) NSData *photoData;

@property (nonatomic,strong) City *city;

@end
这个是目前的City模型,请注意你的City模型当然也必须是CoreModel的子类:
@interface City : CoreModel

@property (nonatomic,copy) NSString *cityName;

@property (nonatomic,copy) NSString *spell;

@end

下面我们构建数据,执行如下数据并执行级联添加:

City *city = [[City alloc] init];
city.hostID = 1;
city.cityName = @"成都";
city.spell = @"ChengDu";
Person *p5 = [[Person alloc] init];
p5.hostID=5;
p5.name = @"张三";
p5.city=city;
[Person insert:p5 resBlock:^(BOOL res) {
    [self show:res];
}];

执行成功,我们查询结果检验:

sqlite> select * from Person;
+----+--------+-----+--------+-----------+--------+--------+-----+
| id | name   | age | height | photoData | hostID | pModel | pid |
+----+--------+-----+--------+-----------+--------+--------+-----+
| 1  | 张三   | 0   | 0.0    |           | 5      |        | 0   |
+----+--------+-----+--------+-----------+--------+--------+-----+
1 rows in set (0.01 sec)


sqlite> select * from City;
+----+----------+---------+--------+-----------+-----+
| id | cityName | spell   | hostID | pModel    | pid |
+----+----------+---------+--------+-----------+-----+
| 1  | 成都     | ChengDu | 1      | Person    | 5   |
+----+----------+---------+--------+-----------+-----+
1 rows in set (0.00 sec)

注:子模型的级联还牵扯一个复杂问题就是:Person有一个模型属性正好也是Person类。不过此种情况已经测试,完美支持。

注意,由于代码是复用的,级联的CURD是不会有任何问题的,这里不再提供进一步的测试。




十六、数组支持:基本类型数组


##### 本功能请参考项目中:Test14VC.m 为了更好的演示本功能,我们再为Person增加一个属性tags,用来表示人的一些标签,请明确,他是字符串数组。
@property (nonatomic,strong) NSArray *tags;

现在我们来构建模型:

Person *p = [[Person alloc] init];
p.hostID=6;
p.name = @"冯成林";
p.tags = @[@"工作狂",@"电影迷",@"成都范",@"梦想青年"];
[Person save:p resBlock:^(BOOL res) {
    [self show:res];
}];

,我们测试以上代码,发现被断言截获,断言说明如下:

错误:请在Person类中为您的NSArray类型的tags属性增加说明信息,实现statementForNSArrayProperties静态方法!

,这个是前面最开始的断言中提到的一种非法使用,当然解决问题的方法很简单,断言也说明的很清楚,您需要告诉CoreModel你的tags数组里面装的是什么类型,实现,格式要求如下:实现statementForNSArrayProperties静态方法,返回一个字典,其实key是数组属性名,value是数组成员的类型字符串,比如此处我们需要在Person类实现方法:

+(NSDictionary *)statementForNSArrayProperties{
    return @{@"tags":NSStringFromClass([NSString class])};
}

,有可能您认为您的数组中装的其实是一系列数字,你也许会这样写:

+(NSDictionary *)statementForNSArrayProperties{
    return @{@"tags":@"NSInteger"};
}

,这样写,我们直接运行一下,发现同样会触发断言:

错误:OC数组内不可能存放NSInteger

,就目前来说,服务器给您的的普通数据你直接用NSString来接收就可以了,当然你可能会想写成NSNumber可以不呢?其实我觉得没有这个必要,因为再者转为NSInteger、CGFloat、Double的流程其实是一致的,所以数组里面装的如果是普通数组类型,请直接用NSString来接收。

我们还是来看看数据库里面存放结果:

sqlite> select * from Person;
+----+-----------+-----+--------+-----------+--------+--------+-----+--------------------------------------------+
| id | name      | age | height | photoData | hostID | pModel | pid | tags                                       |
+----+-----------+-----+--------+-----------+--------+--------+-----+--------------------------------------------+
| 1  | 张三      | 0   | 0.0    |           | 5      |        | 0   |                                            |
| 2  | 冯成林    | 0   | 0.0    |           | 6      |        | 0   | 工作狂,电影迷,成都范,梦想青年 |
+----+-----------+-----+--------+-----------+--------+--------+-----+--------------------------------------------+
2 rows in set (0.02 sec)

最后,有朋友会问, 数组里面装装的如果是字典怎么办?这点上,在面向对象开发,字典一定是可以转为模型的。不建议继续玩字典。 数组里面装的如果是数组怎么办?转为NSData操作 关于数组里面装的是NSData和自定义模型,下面马上为您呈现。




十七、数组支持:NSData类型数组


##### 本功能请参考项目中:Test15VC.m 首先,我们增加字段,请明确字段数组里面放的是NSData数据类型:
@property (nonatomic,strong) NSArray *dreams;

,然后我们需要申明dreams数组内存放的是什么数据类型:

+(NSDictionary *)statementForNSArrayProperties{
    return @{@"tags":NSStringFromClass([NSString class]),@"dreams":NSStringFromClass([NSData class])};
}

,好了,下面我们开始构建数据:

Person *p = [[Person alloc] init];
p.hostID=7;
p.name = @"大雄";
p.dreams = @[
             [self dataWithImageName:@"p1"],
             [self dataWithImageName:@"p2"],
             [self dataWithImageName:@"p3"],
             ];
[Person save:p resBlock:^(BOOL res) {
    [self show:res];
}];

,保存结果请参考框架数组支持:NSData类型数组演示效果。




十八、数组支持:自定义模型数组


##### 本功能请参考项目中:Test16VC.m 为了演示本功能,我们新增Pen模型,并在Person模型中新增pens属性:
Pen模型
@interface Pen : CoreModel

@property (nonatomic,copy) NSString *color;

@property (nonatomic,assign) CGFloat price;

@end
Person中新增pens属性:
@property (nonatomic,strong) NSArray *pens;

,当然你不能忘记申明pens里面放的是什么数据类型:

+(NSDictionary *)statementForNSArrayProperties{
    return @{@"tags":NSStringFromClass([NSString class]),@"dreams":NSStringFromClass([NSData class]),@"pens":NSStringFromClass([Pen class])};
}

,下面我们构建模型数据,并执行保存操作:

Pen *pen1=[[Pen alloc] init];
pen1.hostID=1;
pen1.color = @"red";
pen1.price = 12.5;
Pen *pen2=[[Pen alloc] init];
pen2.hostID=1;
pen2.color = @"blue";
pen2.price = 9.8;
Person *p = [[Person alloc] init];
p.hostID = 8;
p.name = @"静香";
p.pens=@[pen1,pen2];
[Person save:p resBlock:^(BOOL res) {
    [self show:res];
}];

,执行成功,我们看看数据库里面的保存记录:

sqlite> select * from Person; +----+--------+-----+--------+-----------+------+--------+--------+--------+-----+ | id | name | age | height | photoData | tags | dreams | hostID | pModel | pid | +----+--------+-----+--------+-----------+------+--------+--------+--------+-----+ | 1 | 静香 | 0 | 0.0 | | | | 8 | | 0 | +----+--------+-----+--------+-----------+------+--------+--------+--------+-----+ 1 rows in set (0.01 sec)

sqlite> select * from Pen; +----+-------+-------+--------+--------+-----+ | id | color | price | hostID | pModel | pid | +----+-------+-------+--------+--------+-----+ | 1 | red | 12.5 | 1 | Person | 8 | | 2 | blue | 9.8 | 1 | Person | 8 | +----+-------+-------+--------+--------+-----+ 2 rows in set (0.01 sec)




十九、综合实战:网络数据一键CURD


##### 本功能请参考项目中:Test17VC.m #####为了演示本功能,我为大家准备了一个测试接口,我们所有准备已经做好,直接开工: #### 注意:本例是CoreModel最正经的用法,也是我写本框架的最直接的目的所在: #### 本例是自定义模型属性数组支持与子模型级联的综合演示:
NSString *url = @"http://211.149.151.92/mytest/Test/test3";
CoreSVPLoading(@"加载中", YES)
[CoreHttp getUrl:url params:nil success:^(NSDictionary *dict) {
    
    Person *p = [Person objectWithKeyValues:dict[@"data"][@"dataData"][@"person"]];
    
    [Person save:p resBlock:^(BOOL res) {
        
        [self show:res];
    }];
    
} errorBlock:nil];

,处理成功,我们来看看表记录:

sqlite> select * from Person;
+----+--------+-----+--------+-----------+------+--------+--------+--------+-----+
| id | name   | age | height | photoData | tags | dreams | hostID | pModel | pid |
+----+--------+-----+--------+-----------+------+--------+--------+--------+-----+
| 1  | 张三   | 18  | 185.0  |           |      |        | 100    |        | 0   |
+----+--------+-----+--------+-----------+------+--------+--------+--------+-----+
1 rows in set (0.00 sec)

sqlite> select * from City;
+----+----------+---------+--------+--------+-----+
| id | cityName | spell   | hostID | pModel | pid |
+----+----------+---------+--------+--------+-----+
| 1  | 成都   | ChengDu | 100    | Person | 100 |
+----+----------+---------+--------+--------+-----+
1 rows in set (0.00 sec)

sqlite> select * from Pen;
+----+-------+-------+--------+--------+-----+
| id | color | price | hostID | pModel | pid |
+----+-------+-------+--------+--------+-----+
| 1  | red   | 18.55 | 100    | Person | 100 |
| 2  | green | 22.22 | 101    | Person | 100 |
+----+-------+-------+--------+--------+-----+
2 rows in set (0.06 sec)




二十、 第四季与第五季预告

第四季:CoreCache 动态缓存
第五季:CoreList 列表终结者

第三季CoreModel在我看来是一个底层工具,他的核心价值是为CoreCache和CoreList服务,就在CoreModel中你会发现大量的代码是在本季没有提到,请暂时忽略它吧。





成都时点软件开发有限公司冯成林原创,因你而精彩!

支持时点软件发展(公司前期做全国APP外包),为时点提供业务资源与信息,我们感激不尽!!


[![image](https://github.com/CharlinFeng/Resource/blob/master/ShiDian/shidian.png)](http://ios-android.cn)

coremodel's People

Contributors

charlinfeng avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

coremodel's Issues

属性是int时对应的数据库中类型是text类型

当建立的属性类型是int类型时,code=i,运行方法“+ (NSString *)sqliteType:(NSString *)fieldType”时,得出的 sqliteType = TEXT_TYPE,这是因为nsstring对应的字段里有i,所以导致创建的数据库中对应字段类型不正确。

hostId

对于“核心字段:hostID是服务器主键,任何使用CoreModel的模型必须拥有唯一的hostID,如果您没有hostID,请构建。” 我看过demo后,有几个问题不是太明白,请教一下:
1.你怎么知道hostID对应服务器中的哪个字段
2.支持多个主键吗?联合主键
3.怎么构建hostID

删除app后重新安装,出现bug

删除app后重新安装,会一直提示以下问题,请问怎么解决,谢谢!
注意:你操作的模型SYPersonModel在数据库中没有对应的数据表,框架正在全自动创表,并稍后自动重新执行您的操作,请放心!

创建表崩在这

                        [childModel setValue:[self modelName] forKey:@"pModel"];

表示很不解

sql语句中会出现单引号错误

sql语句中会出现单引号错误

@"INSERT INTO KFChatMessage (messageFor,messageType,messageBody,messageTime,list,hostID,pModel,pid) VALUES (0,0,'I'm ','','321,654,987',1448271114,'',0);"

NSObject的NSString属性里有可能出现例如:I'm这种字符串,会造成插入和更新数据失败

希望hostID类型是字符串

因为很多现有的接口没有返回服务器数据库的id,比如我们的返回数据里是这样的值“557c5b1e4d952d620cd40725”,所以期望能改下hostID的类型。

可以加一个 .gitignore 么

Created by http://www.gitignore.io

Xcode

build
.xcodeproj/
!.xcodeproj/project.pbxproj
!
.xcworkspace/contents.xcworkspacedata

Objective-C

OS X

.DS_Store

Xcode

build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
profile
*.moved-aside
DerivedData
*.hmap
*.ipa

CocoaPods

Pods
No newline at end of file

关于数据库存储的问题

数据库存model的时候不能存数组是不?我model里存了个数组就崩了 数组注释掉就不崩了

错误:你操作的模型NSArray在数据库中没有对应的数据表!

关于取sql中的数据问题

在我请求sql数据的时候,返回的是以下的错误
网络请求错误日志(code=1):URL地址有错,要么服务器没有响应。总之连接就有错。
请求URL=(null)?page=1
我想知道的是关于这个url是在哪里设置的,关于取这个sql中的数据,这个地方你能不能介绍的更详细一点

select查找的一个BUG

NSObject+Select.h 137行少了下面这句

if(selectResultsBlock != nil) selectResultsBlock(resultsM);

最新版本的好像有BUG

注意:单条数据插入时,你操作的模型IMInfoModel在数据库中没有对应的数据表!框架正在全自动创表,并稍后自动重新执行您的操作,请放心!
把app删除,重新跑一遍,一直说没建表

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.