(4)代碼及測試【利用objective-c的runtime特性,結合FMDB實現輕量級的ORM】

 版權聲明:本文爲博主原創文章,未經博主容許不得轉載。git

(本ORM的源碼已經上傳到github上 (https://github.com/helloclq/BCSqliteORM_FMDB),你們能夠下載測試,如發現什麼問題或意見,歡迎你們提出並指正,oschina上的地址爲:http://git.oschina.net/BlockCheng/BCSqliteORM_FMDB  )github

0、測試代碼及結果

根據前面的UML,我完成了基本的code,先看下測試結果:sql

測試代碼:shell

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //build two model
        ClassEntity* classeEntity = [ClassEntity new];
        classeEntity.className = @"Software02";
        classeEntity.classId = 1;

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

        //init and mapping ,or open an existing database file,
        BCORMHelper* helper = [[BCORMHelper alloc]initWithDatabaseName:@"test.db" enties: @[ [ClassEntity class],[StudentEntity class]]];

        
        //insert
        for (int i  = 0 ;i <  10; i ++) {
            classeEntity.classId =  i % 10;
            classeEntity.className = [NSString stringWithFormat:@"Class E_%d_%@",i,[NSDate date]];
            [helper save:classeEntity];
        }

        for (int i  = 0 ;i <  100; i ++) {
            student.studentNum = 421125 + i ;
            student.classId = i % 10 + 1;
            student.studentName = [NSString stringWithFormat:@"student_%d_%@",i,[NSDate date]];
             [helper save:student];
        }

        //query
        BCSqlParameter *queryParam  = [[BCSqlParameter  alloc] init];
        queryParam.entityClass = [StudentEntity class];
        queryParam.propertyArray = @[@"age",@"classId",@"score",@"studentName",@"studentNum"];
        queryParam.selection = @"classId = ? and studentNum=?";
        queryParam.selectionArgs = @[@1,@421125];
        queryParam.orderBy = @" studentNum  asc";
        id entity  = [helper queryEntityByCondition:queryParam];
        NSLog(@"entity:----%@",entity);

        //another way to query
        entity  = [helper queryEntityByCondition:BCQueryParameterMake([StudentEntity class], @[@"age",@"classId",@"score",@"studentName",@"studentNum"], @"classId = ? and studentNum=?", @[@1,@421128], nil,@" studentNum  asc",  -1, -1)];
        NSLog(@"entity:----%@",entity);

        //query many models
        queryParam.propertyArray = nil;
        queryParam.selection = @"classId = ?";
        queryParam.selectionArgs = @[@1];
        NSArray* entities  = [helper queryEntitiesByCondition:queryParam];
         NSLog(@"entities:----%@",entities);
        //query by condition
        entities  = [helper queryEntitiesByCondition:BCQueryParameterMake([ClassEntity class], nil, @"classId = ?", @[@1], nil, nil, -1, -1)];
         NSLog(@"entities:----%@",entities);

        //update a model
        student.studentName = @"BlockCheng_Update";
         [helper update:student];

        //query many model by condition
        entity  = [helper queryEntityByCondition:BCQueryParameterMakeSimple([StudentEntity class], nil, @"studentNum=?", @[@421138])];
        NSLog(@"entity:----%@",entity);

        //delete
        [helper remove:entity];

        //query many model by condition
        entity  = [helper queryEntityByCondition:BCQueryParameterMakeSimple([StudentEntity class], nil, @"studentNum=?", @[@421138])];
        NSLog(@"entity:----%@",entity);

        //update many model by condition
        [helper updateByCondition:BCUpdateParameterMake([StudentEntity class], @"studentName=?", @[@"new_name"], @"studentNum=?", @[@421125])];

        entity  = [helper queryEntityByCondition:BCQueryParameterMakeSimple([StudentEntity class], nil, @"studentNum=?", @[@421125])];
        NSLog(@"entity:----%@",entity);

        //delete by condition
        [helper deleteByCondition:BCDeleteParameterMake([StudentEntity class],  @"studentNum < ?", @[@421135])];

    }
    return 0;
}

控制檯輸出:數據庫

一、建表app

BCORMHelper.m:412	sqlite file path:/Users/BlockCheng/Library/Application Support/test.db
BCORMHelper.m:341	add a new class:ClassEntity
BCORMHelper.m:345	execute a sql:
SSQL:::[

DROP TABLE IF EXISTS "class" ;

]
BCORMHelper.m:263	execute a sql:
SSQL:::[

CREATE TABLE 'class' ('id'  INTEGER  PRIMARY KEY  AUTOINCREMENT   NOT NULL , 'name'  TEXT   NOT NULL);

]
BCORMHelper.m:341	add a new class:StudentEntity
BCORMHelper.m:345	execute a sql:
SSQL:::[

DROP TABLE IF EXISTS "StudentEntity" ;

]
BCORMHelper.m:263	execute a sql:
SSQL:::[

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

]
BCORMHelper.m:281	build table index.....
BCORMHelper.m:297	execute a sql:
SSQL:::[

CREATE INDEX idx_StudentEntity_num ON StudentEntity('num');CREATE INDEX idx_StudentEntity_classid ON StudentEntity('classid');

]

二、插入insert測試

BCORMHelper.m:520	save:
SSQL:::[

INSERT INTO class ( 'id','name') VALUES (:id ,:name )

] 
 args:{
    id = 2;
    name = Software02;
}

三、查詢
ui

BCORMHelper.m:598	queryEntityByCondition:
SSQL:::[

SELECT  age,  classid,  score,  name,  num  FROM StudentEntity  WHERE classid = ? and num=?  ORDER BY  num  asc 

] 
  arg:(
    1,
    421125
)

四、更新:atom

BCORMHelper.m:822	update:
SSQL:::[

UPDATE StudentEntity SET age = :age,name = :name,num = :num,score = :score,classid = :classid  WHERE num ='421224'

] 
 args:{
    age = 12;
    classid = 10;
    name = "BlockCheng_Update";
    num = 421224;
    score = 80;
}

五、刪除:spa

BCORMHelper.m:971	remove:
SSQL:::[

DELETE FROM StudentEntity   WHERE num ='421138'

]

六、條件更新:

BCORMHelper.m:899	updateByCondition:
SSQL:::[

UPDATE StudentEntity SET  name=?  WHERE num=? 

] 
 args:(
    "new_name",
    421125
)

七、條件刪除

BCORMHelper.m:1016	deleteByCondition:
SSQL:::[

DELETE  FROM StudentEntity   WHERE num < ? 

] 
 args:(
    421135
)

從測試結果看,徹底達到了前面個人預期


一、用法_建表_映射

因爲本orm是基於fmdb的,故包好FMDB和相應的庫是必須的!!

而後,包含本ORM頭文件

#import "BCDB.h"

須要和數據庫映射的實體須要實現 BCORMEntityProtocol 協議

@protocol BCORMEntityProtocol <NSObject>

@required
/**
 *propertyName: databaseInfo;
 **/
+(NSDictionary*)tableEntityMapping;
@optional
+(NSString*)tableName;
/**
 *propertyName----- table index;
 **/
+(NSArray*)tableIndexArray;

@end

例如:

@interface ClassEntity : NSObject<BCORMEntityProtocol>
@property (nonatomic,assign)NSInteger classId;
@property (nonatomic,copy)NSString* className;
@end


@implementation ClassEntity
- (NSString *)description
{
    return [NSString stringWithFormat:@"[Class:id(%ld) name:(%@)]:%p",self.classId,self.className,self];
}

+(NSString*)tableName
{
    return @"class";
}

+(NSDictionary*)tableEntityMapping
{
    return @{ @"classId":BCSqliteTypeMakeIntPrimaryKey(@"id", YES),
              @"className":BCSqliteTypeMakeText(@"name", NO)
              };
}
@end

而後建立數據庫或打開現有數據庫便可:

BCORMHelper* helper = [[BCORMHelper alloc]initWithDatabaseName:@"test.db" enties: @[ [ClassEntity class],[StudentEntity class]]];

執行後,若是數據庫不存在,即可看到建表過程,輸入如:上面的【0、測試代碼及結果-----一、建表

二、insert實體到sqlite

完成【一、用法_建表_映射】後,構造一個實體插入:

ClassEntity* classeEntity = [ClassEntity new];
classeEntity.className = @"Software02";
classeEntity.classId = 1;
 [helper save:classeEntity];

遍成功地插入了一條數據,或者更新了數據:結果見 上面的【0、測試代碼及結果-----二、插入insert

三、update更新實體

更新一個已存在的數據的方式爲:

 classeEntity.className = @"Software01";
  [helper update:classeEntity];

輸入爲:

BCORMHelper.m:822	update:
SSQL:::[

UPDATE class SET id = :id,name = :name  WHERE id ='9'

] 
 args:{
    id = 9;
    name = Software01;
}

也能夠根據條件更新:

//update many model by condition
        [helper updateByCondition:BCUpdateParameterMake([StudentEntity class], @"studentName=?", @[@"new_name"], @"studentNum=?", @[@421125])];

結果見 【0、測試代碼及結果-----六、條件更新:


四、query查詢一個或多個

查詢能夠本身構造參數:

//query
        BCSqlParameter *queryParam  = [[BCSqlParameter  alloc] init];
        queryParam.entityClass = [StudentEntity class];
        queryParam.propertyArray = @[@"age",@"classId",@"score",@"studentName",@"studentNum"];
        queryParam.selection = @"classId = ? and studentNum=?";
        queryParam.selectionArgs = @[@1,@421125];
        queryParam.orderBy = @" studentNum  asc";
        id entity  = [helper queryEntityByCondition:queryParam];
        NSLog(@"entity:----%@",entity);

也能夠:

//another way to query
  id entity  = [helper queryEntityByCondition:BCQueryParameterMake([StudentEntity class], @[@"age",@"classId",@"score",@"studentName",@"studentNum"], @"classId = ? and studentNum=?", @[@1,@421128], nil,@" studentNum  asc",  -1, -1)];
        NSLog(@"entity:----%@",entity);

輸出見【0、測試代碼及結果-----三、查詢

五、delete刪除實體

能夠直接remove一個已存在的實體:

//delete
[helper remove:entity];

或者根據條件來刪除:

  //delete by condition
 [helper deleteByCondition:BCDeleteParameterMake([StudentEntity class],  @"studentNum < ?", @[@421135])];

輸出見【0、測試代碼及結果-----七、條件刪除


六、結束語

   本ORM的源碼已經上傳到github上 (https://github.com/helloclq/BCSqliteORM_FMDB),你們能夠下載測試,如發現什麼問題或意見,歡迎你們提出並指正,

稍後,我也會傳一份到oschina的git上,後面我持續更新該orm源碼。

相關文章
相關標籤/搜索