動態(tài)表單設計

一、選型分析

動態(tài)表單是一種要求比較靈活的使用場景,根據(jù)動態(tài)的模型來生成對應的表單,并且能夠很方便的隨時修改結構。

通過分析,整理了三種可能符合的方案。

1.MySQL物理表方案

每個模型對應生成一張MySQL物理表,并生成對應代碼,動態(tài)裝載到Spring。

此方案的優(yōu)點是:

a. 做到了代碼和數(shù)據(jù)的隔離,并且能很好的適應傳統(tǒng)框架。

b. 查詢統(tǒng)計比較方便

也有很多弊端:

a. 實現(xiàn)成本高,且需要解決運行時不停服新增表單對應的功能。

b. 變更不方便,每次結構變更需要修改物理表,并且重新生成對應的代碼。

2.MySQL邏輯表方案

一張基礎屬性表+一張表單結構表+一張數(shù)據(jù)大表

image.png

a. 通過基礎屬性表創(chuàng)建結構映射表。

b. 實際的數(shù)據(jù)存儲在大表中,字段對應到映射中的模型。

此方案的優(yōu)點:

a. 實現(xiàn)成本低,邏輯控制數(shù)據(jù)關系。

b. 非常輕松的隨時變更結構,只需要修改、刪除或新增記錄就可以實現(xiàn)效果。

缺點:

a. 不適合大量數(shù)據(jù)的操作,數(shù)據(jù)大表會極度膨脹。

b. 數(shù)據(jù)隔離性較差,做數(shù)據(jù)查詢和統(tǒng)計比較麻煩。

3.NoSQL物理表方案

結合前2種方案,我們試圖尋找一種既能做到數(shù)據(jù)隔離,也能方便后期隨時修改結構的方案。

通過NoSQL文檔類型數(shù)據(jù)庫來解決靈活變更結構且能保證數(shù)據(jù)表的隔離。

在這里,我們選擇的是MongoDB。下面,就按照這個思路展開詳細設計。

二、MongoDB物理表方案設計

1. 邏輯設計

結構采用MySQL來存儲維護,實際的數(shù)據(jù)采用MongoDB來存儲。

表單結構關系設計

image.png

組件元素表的每條記錄cell對應的是系統(tǒng)中支持的組件,包含了組件的類型、組件名稱等屬性。

字段對應到的是組件元素,這里可能是一個字段對應一個組件元素,也有可能是多個字段對應一個組件元素,因為組件元素有可能是復合組件,如身份信息組件等。

字段對應好后組合成字段集合,也就是實際的表單結構。

image.png

2.MongoDB表設計

公共字段設計

字段名 字段類型 備注
_id string 默認字段,值根據(jù)uid生成,方便查詢和去重
uid string 業(yè)務uid

3.MongoDB操作API設計

因為表都是動態(tài)的,所以不適合用spring自帶的mongoDb cruid框架,對于輸入和輸出數(shù)據(jù)需要用json來表現(xiàn)。

項目中定義了 MongoDbTemplate操作類來對動態(tài)表操作數(shù)據(jù),具體方法如下:

/**
 * 查詢記錄
 * @param queryDTO
 * @return
 */
public JSONArray queryData(DocumentQueryDTO queryDTO)

/**
 * 查詢單條記錄
 * @param collectionName
 * @param uid
 * @return
 */
public JSONObject selectOne(String collectionName, String uid)

/**
 * 分頁查詢
 * @param queryPageDTO
 * @return
 */
public PageResult selectPage(DocumentQueryPageDTO queryPageDTO) 

/**
 * 單條記錄插入
 * @param collectionName
 * @param jsonObject
 * @return
 */
public boolean insertOrUpdate(String collectionName, JSONObject jsonObject)

/**
 * 批量插入
 * @param collectionName
 * @param jsonArray
 * @return
 */
public boolean insertOrUpdateMany(String collectionName, JSONArray jsonArray)

/**
 * 刪除文檔
 * @param collectionName
 * @param uid
 * @return
 */
public boolean removeDocument(String collectionName, String uid)

/**
 * 根據(jù)條件刪除
 * @param collectionName
 * @param filter
 * @return
 */
public boolean removeDocumentByFilter(String collectionName, Bson filter)</pre>

查詢入?yún)ocumentQueryDTO類字段信息如下

@Data
public class DocumentQueryDTO implements Serializable {

    private String collectionName;

    /**
     * 過濾條件
     * com.mongodb.client.model.Filters類來構建條件
     */
    private Bson filter;

    /**
     * 排序字段
     */
    private SortParam sortParam;

}

SortParam類字段信息


@Data
public class SortParam {

    /**
     * 排序字段名
     */
    private String sortKey;

    /**
     * 排序類型
     * ASC 升序
     * DESC 降序
     */
    private SortEnum sort;

}

Filters使用

//單條件查詢
Bson filter = Filters.eq("uid", "123");

//多條件查詢
Bson filter = Filters.and(Filters.eq("uid", "123"), Filters.eq("age", 12));

//也可支持or、in等操作符。</pre>

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容