用node.js實現ORM的一種思路

来源:http://www.cnblogs.com/jyk/archive/2017/10/24/7722469.html
-Advertisement-
Play Games

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查詢,還可以按照其他欄位來查詢,比如分類欄位。這樣效率就可以得到提升。

  先開個頭,還有後續。。。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 函數外部聲明有什麼作用? 讓我們定義的函數應用範圍更廣,生命更長久。共用。 也就是說所有的外部函數都可以直接調用。 ...
  • 觸發器 觸發器(trigger)是一些過程,與表關係密切,用於保護表中的數據,當一個基表被修改(INSERT、UPDATE或DELETE)時,觸發器自動執行,例如通過觸發器可實現多個表間數據的一致性和完整性。觸發器和應用程式無關。 觸發器的類型有三種: (1)DML觸發器。Oracle可以在DML( ...
  • host,$this->uid,$this->pwd,$this->dbname); //執行sql語句 $reslut = $db->query($sql); if(!$reslut){ die($db->error); } //從結果集對象裡面取數據 if($type==1) ... ...
  • 前言 因為業務要求api的一次請求響應時間在10ms以內,所以傳統的資料庫查詢操作直接被排除(網路io和磁碟io)。通過調研,最終使用了bieset,目前已經正常運行了很久 bitset介紹 看JDK中的解釋簡直一頭霧水,用我自己的理解概括一下 1. bitset的內部實現是long數組 2. se ...
  • 你好博客園!你好世界! ...
  • jsp為用戶提供了9個內置對象,該內置對象由容器進行實例化,用戶直接使用即可; 1 四種屬性範圍 所謂的屬性保存範圍:指一個設置的對象可以在幾個頁面中保存可以繼續使用; 屬性操作方法: public void setAttribute(String name, Object obj) 設置屬性的名稱 ...
  • 1、算數運算 2、比較減運算 3、賦值運算 4、邏輯運算 5、成員運算 ...
  • 十一假期後就有點懶散,好長時間都沒想起來寫東西了。另外最近在打LOL的S賽。接觸LOL時間不長,雖然平時玩的比較少,水平也相當菜,但是像這種大型的賽事有時間還是不會錯過的。主要能夠感受到選手們對競技的激情,對瞬息萬變的戰局的應變,非常精彩。KeKe~~。 這一篇主要對UVW的源碼討論來收個尾,就介紹 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...