日本电影一区二区_日本va欧美va精品发布_日本黄h兄妹h动漫一区二区三区_日本欧美黄色

AppBoxFuture(低代碼快速開發(fā)框架)- 另類的ORM實(shí)現(xiàn)

??通常的ORM實(shí)現(xiàn)基于配置或注釋,由反射或Emit生成相應(yīng)的Sql語句,然后將Sql發(fā)送給數(shù)據(jù)庫解析Sql字符串生成AST再交給優(yōu)化器處理后執(zhí)行,返回的數(shù)據(jù)再經(jīng)由反射或Emit轉(zhuǎn)換為相應(yīng)的實(shí)體實(shí)例。作者認(rèn)為上述方式主要存在以下兩個(gè)問題:

  1. 實(shí)體類代碼是硬編碼的,如果實(shí)體類定義變更必須重新編譯應(yīng)用再部署,不利于實(shí)現(xiàn)運(yùn)行時(shí)動(dòng)態(tài)變更實(shí)體定義;
  2. CRUD操作轉(zhuǎn)換為Sql的實(shí)現(xiàn)復(fù)雜,且需要針對(duì)不同的數(shù)據(jù)庫做適配優(yōu)化。

??由于作者追求極致簡(jiǎn)單的系統(tǒng)架構(gòu)以及絲般順滑的開發(fā)體驗(yàn),所以采用了另類的方式在框架內(nèi)實(shí)現(xiàn)了ORM,之于另類在什么地方我們先通過一些簡(jiǎn)單示例后再來說明一下實(shí)現(xiàn)原理。

一、CRUD操作

??還是用系統(tǒng)自帶的Emploee模型作為示例,在IDE新建服務(wù)模型添加以下代碼保存發(fā)布后可通過主菜單->Service->Invoke運(yùn)行測(cè)試:

AppBoxFuture(低代碼快速開發(fā)框架)- 另類的ORM實(shí)現(xiàn)

//事務(wù)新建兩條記錄var emp1 = new Entities.Emploee();emp1.Name = “Rick”;emp1.Account = “rick@appbox.dev”;emp1.Birthday = new DateTime(1977, 3, 16);var emp2 = new Entities.Emploee();emp2.Name = “Johne”;emp2.Account = “johne@appbox.dev”emp2.Birthday = new DateTime(1979, 1, 2);using(var txn = await Transaction.BeginAsync()){ await EntityStore.SaveAsync(emp1, txn); await EntityStore.SaveAsync(emp2, txn); await txn.CommitAsync();}//查詢記錄var q = new TableScan<Entities.Emploee>();q.Filter(t => t.Name == “Rick”);var emps = await q.ToListAsync();//更新記錄emps[0].Name = “Rick Lu”;await EntityStore.SaveAsync(emps[0]);//刪除記錄await EntityStore.DeleteAsync(emps[0]);

??以上只是已實(shí)現(xiàn)的一些Api示例,復(fù)雜的如根據(jù)索引查詢、聚合查詢等Api正在設(shè)計(jì)開發(fā)中。

二、實(shí)現(xiàn)原理

設(shè)計(jì)時(shí):

??這部分實(shí)現(xiàn)重度依賴Roslyn功能,服務(wù)端在開發(fā)人員登錄至IDE后會(huì)通過Roslyn生成虛擬項(xiàng)目。

AppBoxFuture(低代碼快速開發(fā)框架)- 另類的ORM實(shí)現(xiàn)

  • 實(shí)體模型保存時(shí)服務(wù)端生成虛擬的實(shí)體類代碼,并加入虛擬項(xiàng)目?jī)?nèi);
  • 服務(wù)模型保存時(shí)服務(wù)端生成虛擬的服務(wù)類代碼,并加入虛擬項(xiàng)目?jī)?nèi);發(fā)布時(shí)服務(wù)端的編譯引擎解析虛擬的服務(wù)代碼,然后轉(zhuǎn)換為運(yùn)行時(shí)服務(wù)代碼,再通過Roslyn編譯為動(dòng)態(tài)服務(wù)組件。其中虛擬代碼轉(zhuǎn)換為運(yùn)行時(shí)代碼的過程主要是:
  1. 將實(shí)體屬性取賦值操作(eg: entity.Name = “aa” 或 var temp = entity.Name)轉(zhuǎn)換為針對(duì)運(yùn)行時(shí)Entity類的GetXXX()及SetXXX()操作。**這里需要注意的是運(yùn)行時(shí)只存在一個(gè)Entity類(類似于KVO通過字典表保存屬性值)**;
  2. 將查詢條件轉(zhuǎn)換為可序列化的表達(dá)式,這樣存儲(chǔ)引擎執(zhí)行查詢命令時(shí)可委托clr emit生成過濾指令,存儲(chǔ)引擎在掃描時(shí)直接使用過濾指令計(jì)算滿足條件的記錄。

運(yùn)行時(shí):

??這部分實(shí)現(xiàn)參考以下流程圖,需要注意的是存儲(chǔ)引擎是基于RocksDB的,實(shí)體數(shù)據(jù)轉(zhuǎn)換為KV數(shù)據(jù)(如Key=Id, Value=[字段標(biāo)識(shí):字段值;字段標(biāo)識(shí):字段值]),這樣轉(zhuǎn)換過程就不需要使用反射或Emit。

AppBoxFuture(低代碼快速開發(fā)框架)- 另類的ORM實(shí)現(xiàn)

三、性能測(cè)試

??作者做了簡(jiǎn)單的性能測(cè)試(單節(jié)點(diǎn)I74C8G虛擬機(jī)):

  • 并發(fā)插入不帶索引不帶外鍵的簡(jiǎn)單實(shí)體約28000tps;
  • 通過惟一索引查詢約80000qps;
  • 帶條件掃描少量記錄約35000qps。

四、查詢限制

  • 存儲(chǔ)引擎不支持join,可通過分別查詢出數(shù)據(jù)后利用Linq做join操作;
  • 存儲(chǔ)引擎暫只支持根據(jù)Entity.Id或指定索引查詢排序,不支持自定義排序。

五、本篇小結(jié)

??本篇主要介紹了框架集成的ORM的另類實(shí)現(xiàn),如果您有問題或Bug報(bào)告,請(qǐng)留言或在[Github](https://github.com/enjoycode/appbox.deploy)提交Issue。

相關(guān)新聞

聯(lián)系我們
聯(lián)系我們
公眾號(hào)
公眾號(hào)
在線咨詢
分享本頁
返回頂部
巴林右旗| 海林市| 巴东县| 西盟| 山阴县| 潜山县| 延长县| 桂平市| 宁城县| 泽普县| 富蕴县| 岳西县| 深水埗区| 福安市| 江陵县| 穆棱市| 渑池县| 汽车| 宁晋县| 怀来县| 新田县| 砀山县| 德清县| 页游| 舞钢市| 迁西县| 涟水县| 化隆| 南乐县| 临高县| 铜鼓县| 六安市| 宣威市| 枝江市| 宝坻区| 惠水县| 京山县| 临漳县| 郯城县| 城市| 临湘市|