自定義表單設計的目標是不編寫代碼,由設計人員在界面設計表單配置,用戶就能使用具體的功能模塊了,對於這個目標,首先要解決的就是數據存儲以及數據庫與表單之間的映射問題。
平時如果使用過代碼生成工具,應該對大體的過程有些認識。要么從數據庫讀取已經定義好的表結構,工具生成實體部分代碼,或者是與框架強相關的不同層次的服務代碼;要么從配置文件,再反向生成數據庫代碼或者業務相關代碼;還有可能先定義實體類,再生成其他部分代碼。生成代碼之后,再拷貝到具體的代碼目錄。
這里設計的實體模型與代碼生成工具有部分思路還是相同的,但自定義表單賦予了他更多的功能與職責,首先,他需要面向使用者,用戶、開發人員和設計人員可以在界面上隨時修改實體數據,系統動態同步數據庫與實體模型之間的映射(如果系統已經在運行,實體模型對應的數據庫表數據量比較大,則通過系統自動修改表結構可能會存在問題,需要DBA把數據庫表修改好,再同步實體模型);其次,運行時CRUD等與數據存儲相關操作,需要依賴此實體模型,比如自動生成Id、自動添加審計日志、動態生成各種Sql語句、自動方法驗證等;再者,可以定義與實體模型相關的動態方法執行,比如執行各種基礎的增冊改查以及分頁獲取數據等,或者執行自定義的Sql語句,還可以執行反射或者微服務調用定義等。總之,這里的實體模型做為自定義表單的基礎,承擔了更多的職責。
下面介紹數據庫設計
與實體對象模型對應的數據庫設計有三張表,SpriteObject,主要管理數據庫表信息,並與動態生成的實體數據庫表一一對應;ObjectProperty,主要管理數據庫表字段信息,並與運行時動態生成的數據庫表字段一一對應;ObjectMethods,主要管理運行時方法的調用(自定義表單將大多數常規的數據庫表操作的Sql語句腳本執行都提供了默認的方法實現,提供給表單或者視圖規則使用,大多數常規的CRUD操作不需要另外再單獨定義方法,但對於特殊的業務還是需要自定義Sql腳本執行或者寫代碼完成,但都是通過ObjectMethods管理,並提供給表單規則引擎使用)。ObjectMaps(廢棄),定義實體與實體也就是數據庫表與表之前的關聯關系,但同步維護這個關系會大大增加系統的復雜程度,這里廢棄了,通過后面介紹的規則引擎來管理,CommonParams,方法參數管理,主要管理方法調用的參數,參數設計到實體嵌套,也會大大增加系統的復雜度,這部分也交給規則執行引擎來控制。
核心字段介紹:
SpriteObject,實體對象
- Name,定義實體名稱,與數據庫表名一一對應。
- ApplicationCode,系統Code,可以按照不同微服務管理各個功能模塊。
- Version,版本號,每次修改之后,重新生成版本號,SpriteObject使用非常平凡,需要將SpriteObject相關的數據存儲到緩存中,依賴他的地方需要判斷版本號。
- KeyType,定義主鍵類型,創建數據庫或者添加運行時數據時,根據此字段動態生成Id以及Id值。
- PropertyJsons,屬性數據Json存儲,為了提高系統整體性能,將屬性相關數據序列化到此字段,讀取與訪問實體字段時,不再需要讀取ObjectProperty表數據。
- IsTree,是否為樹,系統自動生成PId、Path、Code、Title等值,並在運行時自動管理
- CreateAudit,自動添加創建CreatorId和CreationTime審計日志及字段,並在運行時自動管理
ObjectProperty對象屬性管理
- Name,字段名稱,與數據庫字段一一對應
- 其他字段都比較好理解
ObjectMethods方法管理
常規的Sql方法已經內置到了系統中,比如增刪改查獲取列表獲取分頁數據等,直接使用方法名稱即可,常規功能模塊,大多數情況這些內置的Sql語句都能夠滿足,這里只是定義常規Sql操作不能滿足的情況,比如各種統計分析等。
- MethodExeType 方法執行類型,可以是Sql語句,反射執行,微服務調用
- MethodExeContent方法執行內容,Sql語句時,執行的是Sql命令(多條時,用";"號隔開);反射時,傳遞程序集以方法,通過反射執行;微服務為微服務名稱
這篇文章主要是介紹實體模型的整體設計思想,后續文章會結合代碼,介紹實體模型與數據庫表之間一一對應關系的實現以及自定義表單核心之一的運行時動態方法執行。