主頁 > 軟體設計 > 打造獨特的ORM開發框架

打造獨特的ORM開發框架

2020-09-13 17:18:36 軟體設計

ORM一直是長久不衰的話題,各種重復造輪子的程序一直在進行,輪子都一樣是圓的,你的又有什么特點呢?

CRL這個輪子造了好多年,功能也越來越標準完備,在開發程序中,解決了很多問題,先上一張腦圖描述CRL的功能

開發框架的意義在于

  • 開發更標準,更統一,不會因為不同人寫的代碼不一樣
  • 開發效率更高,無需重新造輪子,重復無用的代碼,同時簡化開發流程
  • 運行效率得到控制,程式穩定性得到提高

圍繞這幾點,拋開常規的增刪改查,我們來講些與眾不同的

1.與眾不同之一,動態資料源,天生適合分庫分表

可動態配置的功能總比靜態的靈活,擴展性強

目前看到的框架多數訪問物件實體化都類似于

var context = new MsSqlContext(ConnectionString);

在物件初始時,就系結上了資料庫連接串, 這樣寫沒什么問題,但是不好擴展
如:需要動態切換庫,表,根據租戶資訊訪問不同的資料庫,或不同型別的資料庫,或是讀寫分離,這時,急需處理的技術問題就來了,分庫分表的解決方案,讀寫分離的方案
在資料連接系結的情況下,這種問題很不好解決
又或者傳入多個連接串,在呼叫時,手動選擇呼叫的庫或表,對于這種方式,只能說耦合太嚴重,得關心配置,又得關心呼叫,在CRL之前的版本里,有這樣實作過,棄用了

然而根據IOC的理念,這種問題也不是不好解決,讓資料訪問物件抽象化實作就能辦到了
資料查詢方法不再直接呼叫資料訪問物件,而是呼叫抽象工廠方法,由抽象工廠方法來實體化訪問物件,程序表示為

資料查詢方法(組件內) => 抽象工廠(組件內) => 抽象實作(組件外)

基于這樣的理念,CRL在設計之初,就使用了的這樣的方式,以代碼為例

!資料訪問實作

以下實作了分庫分表和mongoDB切換


以下在程式啟動時初始

var builder = new CRL.SettingConfigBuilder();            builder.UseMongoDB();//參考CRL.Mongo 使用MongoDB                                 //注冊自定義定位,按MemberSharding傳入資料定義資料源位置                                 //注冊一            builder.RegisterLocation<Code.Sharding.MemberSharding>((t, a) =>            {                var tableName = t.TableName;                if (a.Name == "hubro")//當名稱為hubro,則定位到庫testdb2 表MemberSharding1                {                    tableName = "MemberSharding1";                    return new CRL.Sharding.Location("testdb2", tableName);                }                //回傳定位庫和表名                return new CRL.Sharding.Location("testdb", tableName);            });            //注冊二            builder.RegisterDBAccessBuild(dbLocation =>            {                if (dbLocation.ManageName == "mongo")                {                    var conn = CRL.Core.CustomSetting.GetConfigKey("mongodb");                    return new CRL.DBAccessBuild(DBType.MongoDB, conn);                }                return null;            });            //注冊三            builder.RegisterDBAccessBuild(dbLocation =>            {                //自定義定位,由注冊一傳入                if (dbLocation.ShardingLocation != null)                {                    return new CRL.DBAccessBuild(DBType.MSSQL, "Data Source=.;Initial Catalog=" + dbLocation.ShardingLocation.DataBaseName + ";User ID=sa;Password=123");                }                return new CRL.DBAccessBuild(DBType.MSSQL, "server=.;database=testDb; uid=sa;pwd=123;");            });

 

!資料訪問類,類似于倉儲的形式,根據實際業務實作
定位使用示例

public class MemberManage : CRL.Sharding.BaseProvider<MemberSharding>{}var instance=new MemberManage();instance.Add(new MemberSharding(){Name="hubro"});

根據定位規則 運行到注冊一,此資料將會插入到 庫testdb2 表MemberSharding1

常規切換示例

public class MongoDBTestManage : CRL.BaseProvider<MongoDBModel2>{    public override string ManageName => "mongo";}var instance=new MongoDBTestManage();instance.Add(new MongoDBModel2(){name="hubro"});

根據資料訪問規則,運行到注冊二,此資料將會插入mongodb

可以看到,在上面代碼中,沒有看到任何資料連接串的傳入,資料的訪問都由初始時動態分配,對于方法呼叫是不透明的,呼叫者不用關心資料源的問題

2.與眾不同之二,表結構自動維護

在新技術的支持下,程式和資料庫的系結關系越來越模糊,現在可能是用的SQLSERVER,回頭可能改成MySql了,或者改成mongoDB
依賴資料庫開發變成越來越不可取,效率也很低
再后來出現了DBFirst方式,雖解決了部份問題,但也很麻煩,如:

建立資料庫模型=>匯入資料庫=>T4模版生成代碼(修修補補)

而使用CRL后,程序一步到位,在別人還在用PM設計表結構索引時,你已經設計好了業務結構,效率杠杠的

撰寫物體類,實作物件訪問=>除錯運行,自動創建表結構(關鍵字,長度,索引)

同時,CRL還提供了手動維護方法,使能夠按物體結構重建/檢查資料表
也提供了物件結構檔案匯出,不用提心檔案的問題
詳細介紹看這里
https://www.cnblogs.com/hubro/p/6038118.html

3.與眾不同之三,動態快取

使用快取可以大大提高程式的運行效率,使用REDIS或MONGODB之類的又需要額外維護
對于單應用程式,程式集內快取非常有用
CRL內置了快取實作和維護
只需按方法呼叫就行了,快取創建維護全自動
如:
從資料庫查

var item = instance.QueryItem(b => b.Id==1)

從快取查

var item = instance.QueryItemFromCache(b=>b.Id==1);

也支持按查詢自定義快取

var query = Code.ProductDataManage.Instance.GetLambdaQuery();//快取會按條件不同快取不同的資料,條件不固定時,慎用query.Where(b => b.Id < 700);int exp = 10;//過期分鐘query.Expire(exp);var list = query.ToList();

 

基于這樣的形式,可以將所有查詢都走快取,再也不用擔心資料庫查詢效率了,簡值中小專案開發利器
詳細介紹看這里
https://www.cnblogs.com/hubro/p/6038540.html

4.與眾不同之四,應對復雜查詢

因為沒有查詢分支的概念,處理復雜的查詢,一票ORM估計得退場了,雖然合理的結構設計會減少查詢復雜度,但誰能保證呢
CRL查詢分支程序如下

主查詢 => CreateQuery子查詢 => 回傳匿名物件篩選LambdaQueryResultSelect => 主查詢嵌套子查詢 => 回傳結果

理論上只要符合呼叫邏輯,可以無限嵌套
示例:

var q1 = Code.OrderManage.Instance.GetLambdaQuery();//主查詢            var q2 = q1.CreateQuery<Code.ProductData>();//創建一個子查詢            q2.Where(b => b.Id > 0);            var view = q2.CreateQuery<Code.Member>().GroupBy(b => b.Name).Where(b => b.Id > 0).Select(b => new { b.Name, aa = b.Id.COUNT() });//GROUP查詢            var view2 = q2.Join(view, (a, b) => a.CategoryName == b.Name).Select((a, b) => new { ss1 = a.UserId, ss2 = b.aa });//關聯GROUP            q1.Join(view2, (a, b) => a.Id == b.ss1).Select((a, b) => new { a.Id, b.ss1 });//再關聯            var result = view2.ToList();            var sql = q1.ToString();

生成SQL列印如下

SELECT t1.[Id] AS Id,t2.[ss1] AS ss1FROM [OrderProduct] t1 with(nolock)INNER JOIN(SELECT t2.[UserId] AS ss1,t3.[aa] AS ss2FROM [ProductData] t2 with(nolock)INNER JOIN(SELECT t3.[Name] AS Name,COUNT(t3.Id) AS aaFROM [Member] t3 with(nolock)WHERE (t3.[Id]>@par1)GROUP BY t3.[Name]) t3 ON (t2.[CategoryName]=t3.[Name])WHERE (t2.[Id]>@par0) ) t2 ON (t1.[Id]=t2.[ss1])

 

不管是JOIN后再GROUP,還是GROUP后再GROUP,還是GROUP后再JOIN,通通不是問題
詳細介紹看這里
https://www.cnblogs.com/hubro/p/6096544.html

5.與眾不同之五,查詢抽象,非關系型資料庫支持

通過對Lambda運算式的決議,可以實作不同的查詢轉換,如MongoDB,或ElasticSearch(目前只實作了MongoDB)
有人問,這樣有什么用呢?
好處就是,在CRL框架下,一套LambdaQuery走天下,不用寫各種差異很大的查詢方法了,在動態資料源的支持下,資料拆分游刃有余
如:
之前有個報表存在MSSQL里,發現資料量太大了,查詢慢,改由MongoDB,程式不用怎么調整,直接在配置里改為MongoDB即可

以MongoDB為例

CRLLambdaQuery=>CRLExpression=>BsonDocument=>MongoDB

在[資料訪問實作]示例中,演示了如何切換到MongoDB
代碼實作見專案:CRL.Mongo

6.題外之六,請使用倉儲模式

在上文提到,好多框架會直接回傳一個資料訪問物件,如

var obj1context.Query<TestEntity>(b=>b.Id==1).ToSingle();

然而這樣會導致濫用,直接在WEB層用,在Service層隨意用,如

var obj2=context.Query<TestEntity2>(b=>b.Id==1).ToSingle();var obj3=context.Query<TestEntity3>(b=>b.Id==1).ToSingle();

某一天,TestEntity3要換庫了,查找一下參考,傻眼了,上百個參考(接手別人的專案,親身體驗過這種痛苦,一個個改)
好在CRL開始就杜絕了這種情況發生,對據的訪問必須通過BaseProvider實作,而BaseProvider就是一個倉儲的形式

7.題外之七,查詢效率

ORM效率無非分兩點,物體映射效率和語法決議效率,

對于映射反映在,一次回傳多行資料,轉換為物體集合

對于語法決議效率,按引數呼叫多次,回傳一行資料,轉換為物體

測式程式和SQL為本機,CPU空閑正常,2核6G服務器

一張圖表明一切(不同機器實際情況可能有差異)

CRL效率雖不是最高的,但也不是最差的,測驗專案見:

https://github.com/hubro-xx/CRL5/tree/master/Test/TestConsole

 

大概列舉了以上幾項,還有好多特有的東西,輪子好不好,東西南北滾滾試試

CRL開發框架雖然寫好長時間,但一直在DEBUG狀態中, 最近又升級了,分離了資料訪問層,不同資料庫參考不同的資料訪問層,資料訪問層實作也很簡單,只需要寫兩個檔案,如MySql,實作MySqlHelper和MySQLDBAdapter
見:https://github.com/hubro-xx/CRL5/tree/master/CRL.Providers/CRL.MySql
同時,版本也升級到5.1,專案結構發生了改變

原始碼地址:https://github.com/hubro-xx/CRL5

CRL目前.NET版本為.net 4.5, 有時間了再整理整理netstandard版本

除了ORM,CRL還帶 動態API,RPC,WebSocket,api客戶端代理實作
https://www.cnblogs.com/hubro/p/11652687.html
微服務注冊,發現,呼叫集成參見:
https://github.com/hubro-xx/CRL5/blob/master/Consul/ConsulTest/Program.cs

 

 



轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/26014.html

標籤:架構設計

上一篇:架構師主要做些什么,你知道嗎?

下一篇:分布式系統環境搭建

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more