使用Node.js實(shí)現(xiàn)ORM的一種思路詳解(圖文)
ORM是O和R的映射。O代表面向?qū)ο螅琑代表關(guān)系型數(shù)據(jù)庫(kù)。二者有相似之處同時(shí)也各有特色。就是因?yàn)檫@種即是又非的情況,才需要做映射的。
理想情況是,根據(jù)關(guān)系型數(shù)據(jù)庫(kù)(含業(yè)務(wù)需求)的特點(diǎn)來(lái)設(shè)計(jì)數(shù)據(jù)庫(kù)。同時(shí)根據(jù)面向?qū)ο螅ê瑯I(yè)務(wù)需求)的特點(diǎn)來(lái)設(shè)計(jì)模型(實(shí)體類)。然后再去考慮如何做映射。但是理想很骨jian感dan,現(xiàn)實(shí)太豐fu滿za。
沒(méi)見(jiàn)哪個(gè)ORM是這么做的,也沒(méi)見(jiàn)哪位高手會(huì)這么做設(shè)計(jì)。那么實(shí)際情況是什么樣子的呢?以.net的Entity Framework為例。
DB frist,就是先設(shè)計(jì)好數(shù)據(jù)庫(kù),然后根據(jù)庫(kù)里的表、主外鍵等自動(dòng)創(chuàng)建實(shí)體類。然后可以通過(guò)LinQToSQL來(lái)操作。這樣創(chuàng)建出來(lái)的實(shí)體類顯然缺乏面對(duì)對(duì)象的特色。
Code frist,就是先設(shè)計(jì)實(shí)體類,然后根據(jù)實(shí)體類和特性來(lái)自動(dòng)創(chuàng)建表和主外鍵、約束等。而為了嚴(yán)謹(jǐn),定義實(shí)體類的時(shí)候需要說(shuō)明一下主外鍵等具有關(guān)系型特色的東東。
如下圖

現(xiàn)在想用node來(lái)做一套引擎。剛剛接觸node,估計(jì)會(huì)有現(xiàn)成的orm吧,不知道他們是怎么做的,先不管他們了,先把自己的思路弄清楚再說(shuō),恩恩。
為啥要選擇node呢?以為他原生支持json。Json在前端那是主場(chǎng),js原生支持json,各種操作都非常流暢舒服。但是json到了后端(C#)就麻煩了,C#原生不支持json,只能作為字符串,或者實(shí)體類序列化的形態(tài)。這就需要轉(zhuǎn)來(lái)轉(zhuǎn)去的,很是麻煩。
而采用node那么后端也可以用js來(lái)編碼,也就是說(shuō)會(huì)原生支持json。這就舒服多了。想想,前端創(chuàng)建json(實(shí)體類),然后整個(gè)提交給后端,后端接到j(luò)son直接進(jìn)行處理(安全驗(yàn)證、業(yè)務(wù)處理),然后直接持久化。是不是很爽!
采用node還有一個(gè)好處,那就是他可以在運(yùn)行時(shí)定義實(shí)體類的屬性,比如增加屬性。這個(gè)在C#里是無(wú)法實(shí)現(xiàn)的。
為啥一定要運(yùn)行時(shí)可以修改實(shí)體類?因?yàn)檫@樣做可以避免實(shí)體類數(shù)量爆炸。
打開(kāi)你的項(xiàng)目,數(shù)一數(shù)定義了多少的實(shí)體類?是不是項(xiàng)目越大實(shí)體類就越多?當(dāng)需要發(fā)生變化,需要給實(shí)體類增加一個(gè)屬性的時(shí)候,是不是需要各種改代碼?雖然VS可以幫我們做很多工作。
所以說(shuō)還是在運(yùn)行時(shí)可以隨意修改實(shí)體類的好,這樣可以極大地避免修改代碼的問(wèn)題。(因?yàn)楦揪蜎](méi)有啥代碼)
這一篇主要是說(shuō)思路,所以先簡(jiǎn)單設(shè)計(jì)一個(gè)json來(lái)表示一下。
設(shè)計(jì)這個(gè)json的目的是,引擎可以根據(jù)json的情況來(lái)拼接成SQL,然后交給數(shù)據(jù)庫(kù)處理。
{
"operationMode":"add",// add\update\delete\select
"tableCount":1, //支持多表的級(jí)聯(lián)添加、修改
"fieldInfo":[{//主表的字段,參與操作的字段,不參與的不用寫(xiě)。第一個(gè)字段是主鍵(不支持多主鍵)
"tableName": "t1", //表名。
"primaryKey":"id",//主鍵字段名。我不想把主鍵字段名限制為必須是“ID”
"_sqlCache": "" ,//緩存的sql語(yǔ)句,每次都拼接sql也挺煩的,弄個(gè)緩存存放拼接好的sql。
"fieldList":{ //涉及到的字段,并不需要把表里的字段都放進(jìn)來(lái),根據(jù)業(yè)務(wù)需求設(shè)計(jì)
//客戶端提交的json與之對(duì)應(yīng)
"field1Name":"field1Value",
"field2Name":"field2Value"
}
},
{ //從表的字段,可以不設(shè)置
"primaryKey": "id", //主鍵字段名。我不想把主鍵字段名限制為必須是“ID”
"foreignKey": "foreignKeyid", //主鍵字段名。我不想把主鍵字段名限制為必須是“ID”
"_sqlCache": "", //緩存的sql語(yǔ)句,每次都拼接sql也挺煩的,弄個(gè)緩存存放拼接好的sql。
"fieldList": { //涉及到的字段(不含外鍵字段),并不需要把表里的字段都放進(jìn)來(lái),根據(jù)業(yè)務(wù)需求設(shè)計(jì)
//客戶端提交的json與之對(duì)應(yīng)
"field1Name": "field1Value",
"field2Name": "field2Value"
}
} // 從表的字段,參與操作的字段,不參與的不用寫(xiě)。第一個(gè)字段是主鍵,第二個(gè)字段是外鍵
],
"findCol":[{
"colName":"col1",
"key1":"abc",
"key2":"abc", //范圍查詢時(shí)使用,比如從幾號(hào)到幾號(hào)
"findKind":" {colName} like {key}" //查詢方式:like、not Like、in、=、between等
}]
}
一般的ORM是以實(shí)體類為核心,要求實(shí)體類的完整,就說(shuō)一個(gè)實(shí)體類要和一個(gè)完整的表做映射。比如要下架一個(gè)商品,一般的做法是先把這個(gè)商品從數(shù)據(jù)庫(kù)里讀取出來(lái)實(shí)例化之后,修改標(biāo)記屬性(字段),然后再把整個(gè)實(shí)體類持久化(保存到數(shù)據(jù)庫(kù))。
但是SQL怎么寫(xiě)呢?一個(gè)update就可以了,不用讀取數(shù)據(jù)的,這樣效率就有點(diǎn)損耗。
那么如果要把一個(gè)分類的商品都下架呢?要把這個(gè)分類里的商品都折騰出來(lái),然后批量改屬性值,在批量持久化。
如果寫(xiě)SQL語(yǔ)句呢?還是那一句SQL,只不過(guò)是把查詢條件換一下,還是不需要折騰數(shù)據(jù)。這種情況下效率的差別就很大了。
而我的這個(gè)思路呢,并不是以面向?qū)ο鬄楹诵牡模且躁P(guān)系型數(shù)據(jù)庫(kù)為核心。
就是說(shuō)不會(huì)把實(shí)體類和表做整體的映射,而是會(huì)把屬性和字段做映射。就是說(shuō)把一個(gè)表里的部分字段拿出來(lái),做成一個(gè)實(shí)體類,然后進(jìn)行操作。比如下架商品的例子
表:商品表
字段:isxiajia = 1
條件:id=1(單商品下架) cate=2 (按照分類下架)
然后生成update語(yǔ)句就可以了。
這是一個(gè)獨(dú)立的“實(shí)體類”,這個(gè)類里面并不需要商品的其他屬性,因?yàn)橹皇窍录懿僮?。另外查詢條件也完全放開(kāi),不是僅僅依據(jù)ID查詢,還可以按照其他字段來(lái)查詢,比如分類字段。這樣效率就可以得到提升。
總結(jié)
以上所述是小編給大家介紹的使用Node.js實(shí)現(xiàn)ORM的一種思路詳解,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
[將免費(fèi)進(jìn)行到底]在Amazon的一年免費(fèi)服務(wù)器上安裝Node.JS, NPM和OurJS博客
此文是介紹如何在Amazon的一年免費(fèi)計(jì)劃上安裝Node.JS, NPM還有搭建OurJS博客系統(tǒng)。,需要的朋友可以參考下2014-08-08
基于NodeJS+MongoDB+AngularJS+Bootstrap開(kāi)發(fā)書(shū)店案例分析
這章的目的是為了把前面所學(xué)習(xí)的內(nèi)容整合一下,這個(gè)示例完成一個(gè)簡(jiǎn)單圖書(shū)管理模塊,因?yàn)橹虚g需要使用到Bootstrap這里先介紹Bootstrap2017-01-01
使用Node.js實(shí)現(xiàn)Clean?Architecture方法示例詳解
這篇文章主要為大家介紹了使用Node.js實(shí)現(xiàn)Clean?Architecture方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
node基于puppeteer模擬登錄抓取頁(yè)面的實(shí)現(xiàn)
本篇文章主要介紹了node基于puppeteer模擬登錄抓取頁(yè)面的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
nodejs動(dòng)態(tài)創(chuàng)建二維碼的方法
這篇文章主要為大家詳細(xì)介紹了nodejs動(dòng)態(tài)創(chuàng)建二維碼的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
Nodejs高擴(kuò)展性的模板引擎 functmpl簡(jiǎn)介
本文給大家分享的是一款nodejs高擴(kuò)展性的模板引擎functmpl的簡(jiǎn)單介紹以及用法詳解,有需要的小伙伴可以參考下2017-02-02
Node.js通過(guò)身份證號(hào)驗(yàn)證年齡、出生日期與性別方法示例
最近工作中需要對(duì)身份證號(hào)的年齡、出生日期與性別進(jìn)行驗(yàn)證,所以這篇文章主要介紹了Node.js通過(guò)身份證號(hào)驗(yàn)證年齡、出生日期與性別的方法,在介紹完node.js的實(shí)現(xiàn)方法后又給大家分類的利用JS實(shí)現(xiàn)的方法,需要的朋友可以參考下。2017-03-03
Node.js控制臺(tái)彩色輸出的方法與原理實(shí)例詳解
這篇文章主要給大家介紹了關(guān)于Node.js控制臺(tái)彩色輸出的方法與原理的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Node.js具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12

