版權聲明:本文爲博主原創文章,未經博主容許不得轉載。git
(本ORM的源碼已經上傳到github上 (https://github.com/helloclq/BCSqliteORM_FMDB),你們能夠下載測試,如發現什麼問題或意見,歡迎你們提出並指正,oschina上的地址爲:http://git.oschina.net/BlockCheng/BCSqliteORM_FMDB )github
本次利用一個常見的數據庫關係例子說明本ORM的基本需求。objective-c
班級、學生 這一對錶,關係爲1對多,班級表主鍵id,學生表主鍵num、外鍵班級id。sql
表結構以下:數據庫
班級表class結構測試
學生student表:atom
程序中對應的實體類分別是:班級實體(ClassEntity),學生實體(Student)spa
其基本objective-c類結構以下:.net
@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
在這個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);
此條的預期是這樣的: 傳入一個實體對象,自動生成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; }
傳入一個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; }
根據傳入的查詢條件,生成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 )
根據傳入的類和條件,生成delete語句。
input:
.entityClass = [StudentEntity class]; .selection = @"studentNum=?"; .selectionArgs = @[@421138];
output:
DELETE FROM StudentEntity WHERE num ='421138'
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 )
如何利用runtime+fmdb,實現上面提到的效果?
怎麼去抽象和封裝,達到知足需求的基本結構類,便於往後使用?
怎麼明瞭地處理實體和數據庫表間的映射關係,簡單易用的語法如何設計?
到底該提供哪些基礎通用功能?