ORM是O和R的映射。O代錶面向對象,R代表關係型資料庫。二者有相似之處同時也各有特色。就是因為這種即是又非的情況,才需要做映射的。 理想情況是,根據關係型資料庫(含業務需求)的特點來設計資料庫。同時根據面向對象(含業務需求)的特點來設計模型(實體類)。然後再去考慮如何做映射。但是理想很骨jian感 ...
ORM是O和R的映射。O代錶面向對象,R代表關係型資料庫。二者有相似之處同時也各有特色。就是因為這種即是又非的情況,才需要做映射的。
理想情況是,根據關係型資料庫(含業務需求)的特點來設計資料庫。同時根據面向對象(含業務需求)的特點來設計模型(實體類)。然後再去考慮如何做映射。但是理想很骨jian感dan,現實太豐fu滿za。
沒見哪個ORM是這麼做的,也沒見哪位高手會這麼做設計。那麼實際情況是什麼樣子的呢?以.net的Entity Framework為例。
DB frist,就是先設計好資料庫,然後根據庫里的表、主外鍵等自動創建實體類。然後可以通過LinQToSQL來操作。這樣創建出來的實體類顯然缺乏面對對象的特色。
Code frist,就是先設計實體類,然後根據實體類和特性來自動創建表和主外鍵、約束等。而為了嚴謹,定義實體類的時候需要說明一下主外鍵等具有關係型特色的東東。
如下圖
現在想用node來做一套引擎。剛剛接觸node,估計會有現成的orm吧,不知道他們是怎麼做的,先不管他們了,先把自己的思路弄清楚再說,恩恩。
為啥要選擇node呢?以為他原生支持json。Json在前端那是主場,js原生支持json,各種操作都非常流暢舒服。但是json到了後端(C#)就麻煩了,C#原生不支持json,只能作為字元串,或者實體類序列化的形態。這就需要轉來轉去的,很是麻煩。
而採用node那麼後端也可以用js來編碼,也就是說會原生支持json。這就舒服多了。想想,前端創建json(實體類),然後整個提交給後端,後端接到json直接進行處理(安全驗證、業務處理),然後直接持久化。是不是很爽!
採用node還有一個好處,那就是他可以在運行時定義實體類的屬性,比如增加屬性。這個在C#里是無法實現的。
為啥一定要運行時可以修改實體類?因為這樣做可以避免實體類數量爆炸。
打開你的項目,數一數定義了多少的實體類?是不是項目越大實體類就越多?當需要發生變化,需要給實體類增加一個屬性的時候,是不是需要各種改代碼?雖然VS可以幫我們做很多工作。
所以說還是在運行時可以隨意修改實體類的好,這樣可以極大地避免修改代碼的問題。(因為根本就沒有啥代碼)
這一篇主要是說思路,所以先簡單設計一個json來表示一下。
設計這個json的目的是,引擎可以根據json的情況來拼接成SQL,然後交給資料庫處理。
{ "operationMode":"add",// add\update\delete\select "tableCount":1, //支持多表的級聯添加、修改 "fieldInfo":[{//主表的欄位,參與操作的欄位,不參與的不用寫。第一個欄位是主鍵(不支持多主鍵) "tableName": "t1", //表名。 "primaryKey":"id",//主鍵欄位名。我不想把主鍵欄位名限製為必須是“ID” "_sqlCache": "" ,//緩存的sql語句,每次都拼接sql也挺煩的,弄個緩存存放拼接好的sql。 "fieldList":{ //涉及到的欄位,並不需要把表裡的欄位都放進來,根據業務需求設計 //客戶端提交的json與之對應 "field1Name":"field1Value", "field2Name":"field2Value" } }, { //從表的欄位,可以不設置 "primaryKey": "id", //主鍵欄位名。我不想把主鍵欄位名限製為必須是“ID” "foreignKey": "foreignKeyid", //主鍵欄位名。我不想把主鍵欄位名限製為必須是“ID” "_sqlCache": "", //緩存的sql語句,每次都拼接sql也挺煩的,弄個緩存存放拼接好的sql。 "fieldList": { //涉及到的欄位(不含外鍵欄位),並不需要把表裡的欄位都放進來,根據業務需求設計 //客戶端提交的json與之對應 "field1Name": "field1Value", "field2Name": "field2Value" } } // 從表的欄位,參與操作的欄位,不參與的不用寫。第一個欄位是主鍵,第二個欄位是外鍵 ], "findCol":[{ "colName":"col1", "key1":"abc", "key2":"abc", //範圍查詢時使用,比如從幾號到幾號 "findKind":" {colName} like {key}" //查詢方式:like、not Like、in、=、between等 }] }
一般的ORM是以實體類為核心,要求實體類的完整,就說一個實體類要和一個完整的表做映射。比如要下架一個商品,一般的做法是先把這個商品從資料庫里讀取出來實例化之後,修改標記屬性(欄位),然後再把整個實體類持久化(保存到資料庫)。
但是SQL怎麼寫呢?一個update就可以了,不用讀取數據的,這樣效率就有點損耗。
那麼如果要把一個分類的商品都下架呢?要把這個分類里的商品都折騰出來,然後批量改屬性值,在批量持久化。
如果寫SQL語句呢?還是那一句SQL,只不過是把查詢條件換一下,還是不需要折騰數據。這種情況下效率的差別就很大了。
而我的這個思路呢,並不是以面向對象為核心的,而是以關係型資料庫為核心。
就是說不會把實體類和表做整體的映射,而是會把屬性和欄位做映射。就是說把一個表裡的部分欄位拿出來,做成一個實體類,然後進行操作。比如下架商品的例子
表:商品表
欄位:isxiajia = 1
條件:id=1(單商品下架) cate=2 (按照分類下架)
然後生成update語句就可以了。
這是一個獨立的“實體類”,這個類裡面並不需要商品的其他屬性,因為只是下架操作。另外查詢條件也完全放開,不是僅僅依據ID查詢,還可以按照其他欄位來查詢,比如分類欄位。這樣效率就可以得到提升。
先開個頭,還有後續。。。