(2)预期+思考【利用objective-c的runtime特性,结合FMDB实现轻量级的ORM】

 版权声明:本文为博主原创文章,未经博主允许不得转载。

(本ORM的源码已经上传到github上 (https://github.com/helloclq/BCSqliteORM_FMDB),大家可以下载测试,如发现什么问题或意见,欢迎大家提出并指正,oschina上的地址为:http://git.oschina.net/BlockCheng/BCSqliteORM_FMDB  )

 本次利用一个常见的数据库关系例子说明本ORM的基本需求。

  班级、学生 这一对表,关系为1对多,班级表主键id,学生表主键num、外键班级id。

  表结构如下:

班级表class结构

082213_HUs1_173728.png

学生student表:

082312_AAPp_173728.png

程序中对应的实体类分别是:班级实体(ClassEntity),学生实体(Student)

其基本objective-c类结构如下:

@interface ClassEntity : NSObject

@property (nonatomic,assign)NSInteger classId;
@property (nonatomic,copy)NSString* className;

@end
@interface StudentEntity : NSObject 
@property (nonatomic,assign)NSInteger classId;
@property (nonatomic,assign)int age;
@property (nonatomic,assign)float score;

@property (nonatomic,assign)NSInteger studentNum;
@property (nonatomic,copy)NSString* studentName;
@end


0、实体类-->建库建表语句

  在这个orm中,我预期的效果是:

  • 如果存在内置的数据库,我只需要传入实体类,就能建立映射,直接操作。

  • 如果不存在内置数据库,我只需要传入实体类,就能自动建好数据库和实体数据库间的映射。

  • 支持主外键,支持索引语句。

input:

 @[ [ClassEntity class],[StudentEntity class]]

output:

CREATE TABLE class (
  id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
  name text NOT NULL DEFAULT('Software01')
);

   【数据库的表名可以任意配置,学生表名可以为StudentEntity】

 CREATE TABLE 'StudentEntity' (
  'num'  INTEGER  PRIMARY KEY   NOT NULL , 
 'age'  INTEGER   NOT NULL   DEFAULT '18'  ,
 'name'  TEXT   NOT NULL   DEFAULT 'blockcheng'  ,
 'score'  REAL   NOT NULL   DEFAULT '80.0'  , 
 'classid'  INTEGER,  CONSTRAINT 'Student_class' FOREIGN KEY ('classid')  REFERENCES 'class'('id')
 );
 CREATE INDEX idx_StudentEntity_num ON StudentEntity (num);


1、实体类对象---->insert 语句

此条的预期是这样的: 传入一个实体对象,自动生成sql,然后经由fmdb,存入sqlite。

input:

        ClassEntity* classeEntity = [ClassEntity new];
        classeEntity.className = @"Software02";
        classeEntity.classId = 2;
        StudentEntity* student = [StudentEntity new];
        student.age = 12;
        student.score = 80;
        student.classId = 2;
        student.studentNum = 421125;
        student.studentName = @"BlockCheng";

output:

 INSERT INTO class ( 'id','name') VALUES (:id ,:name ) 
 
 args:{
    id = 2;
    name = "Software02";
}
INSERT INTO StudentEntity ( 'age','name','num','score','classid') VALUES (:age ,:name ,:num ,:score ,:classid ) 
 
args:{
    age = 12;
    classid = 2;
    name = "BlockCheng";
    num = 421125;
    score = 80;
}


2、实体类对象----->update语句,基于主键

传入一个sqlite中已存在的实体,自动生成update语句,基于主键的条件更新。

input:

        StudentEntity* student = [StudentEntity new];
        student.age = 12;
        student.score = 80;
        student.classId = 2;
        student.studentNum = 421125;
        student.studentName = @"BlockCheng_update";

output:

UPDATE StudentEntity SET age = :age,name = :name,num = :num,score = :score,classid = :classid  WHERE num ='421225' 
 
args:{
    age = 12;
    classid = 2;
    name = "BlockCheng_update";
    num = 421225;
    score = 80;
}


3、查询条件----->select语句--->实体类对象

根据传入的查询条件,生成sql:

input:

        .entityClass = [StudentEntity class];
        .propertyArray = @[@"age",@"classId",@"score",@"studentName",@"studentNum"];
        .selection = @"classId = ? and studentNum=?";
        .selectionArgs = @[@1,@421128];
        .orderBy = @" studentNum  asc";

output:

 SELECT  age,  classid,  score,  name,  num  FROM StudentEntity  WHERE classid = ? and num=?  ORDER BY  num  asc  
 
 arg:(
    1,
    421128
)

4、实体类+条件---->delete语句

根据传入的类和条件,生成delete语句。

input:

        .entityClass = [StudentEntity class];
        .selection = @"studentNum=?";
        .selectionArgs = @[@421138];

output:

DELETE FROM StudentEntity   WHERE num ='421138'


5、指定条件+实体类---->update、delete

update input:

        .entityClass = [StudentEntity class];
        .selection = @"studentNum=?";
        .selectionArgs = @[@421128];
        .update= @"studentName=?"
        .upateArgs=@[@"update_condition"];

update output:

 UPDATE StudentEntity SET  name=?  WHERE num=? 
  
 args:(
    "update_condition",
    421125
)


delete input:

        .entityClass = [StudentEntity class];
        .selection = @"studentNum < ?";
        .selectionArgs = @[@421135];

delete output:

 DELETE  FROM StudentEntity   WHERE num < ?  
 
 args:(
    421135
)


6、思考

如何利用runtime+fmdb,实现上面提到的效果?

  • 怎么去抽象和封装,达到满足需求的基本结构类,便于日后使用?

  • 怎么明了地处理实体和数据库表间的映射关系,简单易用的语法如何设计?

  • 到底该提供哪些基础通用功能?

转载于:https://my.oschina.net/chengliqun/blog/504233

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值