MySQL中實現(xiàn)動態(tài)表單中JSON元素精準匹配的方法示例
前言
在很多有工作流設(shè)置的地方、比如需要在不同的流程中,需要實現(xiàn)流程表單的自定義。在以前的一些業(yè)務(wù)中,我們幾乎都需要用戶來固化表單。這樣的實現(xiàn)方式,非常不友好,擴展性也不強。通常在上線后會需要進行調(diào)整。同時,在調(diào)整時,一般需要用戶先明確流程,然后再反饋給開發(fā)人員,因為當(dāng)時沒有在線的流程表單構(gòu)造器,流程的表單調(diào)整還需要開發(fā)人員來配合。這樣一來,系統(tǒng)的開發(fā)步驟就比較長,一個流程要想走下來,花費的時間代價就非常大。因此,在這樣的需求背景下,有的技術(shù)團隊開始研究動態(tài)表單,將用戶的創(chuàng)造和動手能力直接引入進來。用戶不僅能自定義流程引擎,同時還能基于流程引擎來定義掛載在流程引擎上的表單。
到了這一步,應(yīng)該說是非常友好的,用戶可以深度的參與相關(guān)的設(shè)計,如果想調(diào)整流程。只需要下架舊的流程,然后設(shè)計新的流程,同時把相應(yīng)的表單也設(shè)計好后一同發(fā)布。這樣系統(tǒng)就會啟動新的流程,表單也會自動更新。曾幾何時,這種技術(shù)還是少數(shù)部分用戶玩的,而今再看,就像“舊時王謝堂前燕飛入尋常百姓家”,已經(jīng)沒有了什么神秘的面紗,向大眾展示它背后的一面。
雖然在流程中使用動態(tài)表單,有很好的擴展性和可用性。但是,同時也帶來了一些額外的技術(shù)實現(xiàn)復(fù)雜度,就是在生成動態(tài)表單的時候,表單通常比較復(fù)雜,通常我們需要進行很多表單元素的編輯,還要定義表單的值,各種各樣的表單元素類型。如果我想使用表格來導(dǎo)入這些數(shù)據(jù),應(yīng)該怎么來進行對應(yīng)。導(dǎo)出的時候,怎么精準的寫出數(shù)據(jù)。這對我們在數(shù)據(jù)庫中設(shè)計相應(yīng)的表以及針對動態(tài)表單的數(shù)據(jù)進行表單元素級的精準匹配有了一定的技術(shù)要求。
本文重點不是在于講解如何設(shè)計動態(tài)表單,而是重點講解,如何在將設(shè)計好的動態(tài)表單信息進行提取,比如進行模板數(shù)據(jù)導(dǎo)入的時候,可以根據(jù)不同的表單類型,比如根據(jù)單行文字框的名字來動態(tài)設(shè)置值,也可以在導(dǎo)數(shù)數(shù)據(jù)時,知道將數(shù)據(jù)庫的性別一列保存的1和2翻譯成男和女這兩種屬性。這都需要我們精準的提取表單中的不同的信息,能精準提取表單的文本、類型、默認值域還有其他的表單元素的設(shè)置。通過本文,您可以了解如何正確的操作動態(tài)表單信息,同時了解如何從表單中查找表單元素。
一、動態(tài)表單技術(shù)
為了讓大家了解一些動態(tài)表單可能會包含哪些技術(shù),我還是決定對動態(tài)表單技術(shù)進行簡單的講解,更深入的就不再進行贅述。目的是讓大家對動態(tài)表單有個基本的認識。
1、包含的主要信息
眾所周知,在Web界面的設(shè)計和實現(xiàn)中,表單其實就一個form界面,我們在這個Web界面中可以定義不同的表單元素,比如單行文本框,多行文本域、單選按鈕、多選按鈕、下拉框,而在現(xiàn)代的界面中,對元素的類型做了更進一步的細分,比如時間又可以分為時間選擇器、日期選擇器,其它的常見還有打分控件、計數(shù)器、顏色選擇器、開關(guān)、滑塊等等。在下圖中列出來了常見的一些表單要素。
上面這個就是一個非常典型的表單設(shè)計器,它按照功能區(qū)域可以分為表單元素類型、表單設(shè)計漁區(qū)、屬性設(shè)計漁區(qū)三個部分。從結(jié)構(gòu)來說分為左、中、右三種類型。最左邊的部分是表單中包含的元素類型,這個在上面的內(nèi)容中有所涉及。下面有布局字段,布局的話就是用來控制頁面的元素如何布置,比如一行是擺放三個單行文本域還是擺2個,這些都是通過布局元素來設(shè)置的。 中間就是主題的設(shè)計界面。點擊左邊的元素,然后拖到中間的設(shè)計器中即可。
2、元素屬性設(shè)置
將元素和布局都設(shè)置好之后,一個設(shè)計良好的表單,還需要對表單的屬性信息進行定義,比如表單的名字、它的默認值是什么,如果是下拉框,下拉框的值域又是什么?默認的下拉選項是哪個。表單的元素是否必填,是有其它的數(shù)據(jù)格式校驗類型等等。這些屬性信息都在最右邊的屬性編輯器中進行定義和設(shè)置。在中間的要素設(shè)計器中點擊對應(yīng)的表單元素,可以打開它對應(yīng)的屬性設(shè)置信息。如下圖所示:
通過上面的表單設(shè)計界面,我們就可以實現(xiàn)表單的靈活設(shè)置。
3、表單內(nèi)容
相信大家對于生成的表單內(nèi)容是什么樣的,一定很有興趣吧。下面我們來看一下經(jīng)過上面的動態(tài)表單設(shè)計之后,生成的表單內(nèi)容是什么樣的?具體的格式是什么?首先來點擊預(yù)覽,看一下表單設(shè)計器生成的頁面效果。
點擊“生成json”按鈕可以將動態(tài)表單轉(zhuǎn)成json,這樣我們就可以把表單存儲到數(shù)據(jù)庫中,實現(xiàn)動態(tài)的管理和配置。來看下json的表單生成結(jié)果。
內(nèi)容比較多,我們將表單內(nèi)容復(fù)制到文本編輯器中,然后將json進行格式的美化后來看實際的效果。
"list": [ { "type": "grid", "icon": "icon-grid-", "columns": [ { "span": 12, "list": [ { "type": "input", "icon": "icon-input", "options": { "width": "100%", "defaultValue": "", "required": false, "dataType": "string", "pattern": "", "placeholder": "請輸入姓名", "disabled": false, "maxlength": -1, "showWordLimit": false, "remoteFunc": "func_1721826724000_49979" }, "name": "姓名", "key": "1721826724000_49979", "model": "input_1721826724000_49979", "rules": [ { "type": "string", "message": "姓名格式不正確" } ] } ] }
以上就是我們對上面的動態(tài)表單的相關(guān)知識的介紹。介紹上面的內(nèi)容,主要是為了讓大家對數(shù)據(jù)的格式和樣例有一個基本的掌握。
二、表單數(shù)據(jù)存儲和查詢
在掌握了動態(tài)表單的設(shè)計之后,為了實現(xiàn)可以靈活的管理和檢索,我們還需要將表單的數(shù)據(jù)進行存儲,在需要調(diào)用的時候還需要進行高效的查詢。本節(jié)就簡單的來講一下如何進行動態(tài)表單數(shù)據(jù)的存儲和查詢。數(shù)據(jù)庫采用的是MySQL數(shù)據(jù)庫,版本是5.7,采用的數(shù)據(jù)類型是JSON。
1、數(shù)據(jù)存儲
要想把上述的表單數(shù)據(jù)存儲起來,我們可以有兩種選擇,第一種是將表單的內(nèi)容直接存成字符串,配合后臺的開發(fā)語言來實現(xiàn)表單的存儲。第二種就是利用數(shù)據(jù)庫的特性,直接將數(shù)據(jù)以JSON的形式存儲。第一種方案,數(shù)據(jù)庫簡單,但是應(yīng)用程序復(fù)雜。而第二種方案剛好相反。依然使用了數(shù)據(jù)庫,而且用到了5.7這樣的版本,在MySQL當(dāng)中,是支持我們直接操作和管理JSON類型的數(shù)據(jù)的。因此這里我們采用第二種方案,直接設(shè)計json字段。將動態(tài)表單的內(nèi)容存儲到j(luò)son字段中。設(shè)計的表結(jié)構(gòu)如下:
-- ---------------------------- -- Table structure for ems_equipment_classification_attr -- ---------------------------- DROP TABLE IF EXISTS `ems_equipment_classification_attr`; CREATE TABLE `ems_equipment_classification_attr` ( `equip_class_id` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '設(shè)備分類ID', `attr_config` json NOT NULL COMMENT '屬性信息,以json的形式存儲', `create_uid` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '創(chuàng)建人', `create_time` int(11) NOT NULL DEFAULT 0 COMMENT '創(chuàng)建時間', `modify_uid` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '更新人', `modify_time` int(11) NOT NULL DEFAULT 0 COMMENT '更新時間', `version` int(4) NOT NULL DEFAULT 0 COMMENT '版本號', `inherit_flag` int(4) NOT NULL DEFAULT 1 COMMENT '屬性繼承標(biāo)記,1表示繼承上級屬性,0表示獨立屬性', INDEX `idx_ems_equipment_class_attr_class_id`(`equip_class_id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '設(shè)備分類屬性,以json的形式進行存儲,支持各層級單獨定義,下級分類自動繼承上級分類屬性' ROW_FORMAT = Dynamic;
在上述表中我們有一個attr_config 字段,這個字段設(shè)計成json類型的,主要用來保存動態(tài)表單的值。然后我們使用以下語句來新增一條記錄:
-- ---------------------------- -- Records of ems_equipment_classification_attr -- ---------------------------- INSERT INTO `ems_equipment_classification_attr` VALUES ('3', '{\"formConfig\": {\"size\": \"\", \"cssCode\": \"\", \"refName\": \"vForm\", \"functions\": \"\", \"modelName\": \"formData\", \"rulesName\": \"rules\", \"labelAlign\": \"label-left-align\", \"labelWidth\": 80, \"layoutType\": \"PC\", \"customClass\": \"\", \"jsonVersion\": 3, \"labelPosition\": \"left\", \"onFormCreated\": \"\", \"onFormMounted\": \"\", \"onFormValidate\": \"\", \"onFormDataChange\": \"\"}, \"widgetList\": [{\"id\": \"grid93809\", \"key\": 43585, \"cols\": [{\"id\": \"grid-col-52064\", \"icon\": \"grid-col\", \"type\": \"grid-col\", \"options\": {\"md\": 12, \"sm\": 12, \"xs\": 12, \"name\": \"gridCol52064\", \"pull\": 0, \"push\": 0, \"span\": 12, \"hidden\": false, \"offset\": 0, \"responsive\": false, \"customClass\": []}, \"category\": \"container\", \"internal\": true, \"widgetList\": [{\"id\": \"input36308\", \"key\": 90048, \"icon\": \"text-field\", \"type\": \"input\", \"options\": {\"name\": \"input36308\", \"size\": \"\", \"type\": \"text\", \"label\": \"直徑(DN)\", \"hidden\": false, \"onBlur\": \"\", \"onFocus\": \"\", \"onInput\": \"\", \"disabled\": false, \"onChange\": \"\", \"readonly\": false, \"required\": true, \"clearable\": true, \"maxLength\": null, \"minLength\": null, \"onCreated\": \"\", \"onMounted\": \"\", \"buttonIcon\": \"custom-search\", \"labelAlign\": \"\", \"labelWidth\": null, \"onValidate\": \"\", \"prefixIcon\": \"\", \"suffixIcon\": \"\", \"validation\": \"\", \"columnWidth\": \"200px\", \"customClass\": [], \"labelHidden\": false, \"placeholder\": \"\", \"appendButton\": false, \"defaultValue\": \"\", \"labelTooltip\": null, \"requiredHint\": \"品牌不能為空\", \"showPassword\": false, \"showWordLimit\": false, \"labelIconClass\": null, \"validationHint\": \"\", \"labelIconPosition\": \"rear\", \"onAppendButtonClick\": \"\", \"appendButtonDisabled\": false}, \"formItemFlag\": true}]}, {\"id\": \"grid-col-95927\", \"icon\": \"grid-col\", \"type\": \"grid-col\", \"options\": {\"md\": 12, \"sm\": 12, \"xs\": 12, \"name\": \"gridCol95927\", \"pull\": 0, \"push\": 0, \"span\": 12, \"hidden\": false, \"offset\": 0, \"responsive\": false, \"customClass\": []}, \"category\": \"container\", \"internal\": true, \"widgetList\": [{\"id\": \"select17890\", \"key\": 27039, \"icon\": \"select-field\", \"type\": \"select\", \"options\": {\"name\": \"select17890\", \"size\": \"\", \"label\": \"制動方式\", \"hidden\": false, \"onBlur\": \"\", \"remote\": false, \"onFocus\": \"\", \"disabled\": false, \"multiple\": false, \"onChange\": \"\", \"required\": true, \"clearable\": true, \"onCreated\": \"\", \"onMounted\": \"\", \"filterable\": false, \"labelAlign\": \"\", \"labelWidth\": null, \"onValidate\": \"\", \"validation\": \"\", \"allowCreate\": false, \"columnWidth\": \"200px\", \"customClass\": [], \"labelHidden\": false, \"optionItems\": [{\"label\": \"手動\", \"value\": 1}, {\"label\": \"電動\", \"value\": 2}, {\"label\": \"氣動\", \"value\": \"3\"}, {\"label\": \"液壓控制\", \"value\": 4}, {\"label\": \"其他\", \"value\": 5}], \"placeholder\": \"\", \"defaultValue\": \"\", \"labelTooltip\": null, \"requiredHint\": \"制動方式不能空\", \"multipleLimit\": 0, \"onRemoteQuery\": \"\", \"labelIconClass\": null, \"validationHint\": \"\", \"automaticDropdown\": false, \"labelIconPosition\": \"rear\"}, \"formItemFlag\": true}]}], \"icon\": \"grid\", \"type\": \"grid\", \"options\": {\"name\": \"grid93809\", \"gutter\": 12, \"hidden\": false, \"colHeight\": null, \"customClass\": []}, \"category\": \"container\"}, {\"id\": \"grid40469\", \"key\": 43585, \"cols\": [{\"id\": \"grid-col-77638\", \"icon\": \"grid-col\", \"type\": \"grid-col\", \"options\": {\"md\": 12, \"sm\": 12, \"xs\": 12, \"name\": \"gridCol77638\", \"pull\": 0, \"push\": 0, \"span\": 12, \"hidden\": false, \"offset\": 0, \"responsive\": false, \"customClass\": []}, \"category\": \"container\", \"internal\": true, \"widgetList\": [{\"id\": \"input30722\", \"key\": 90048, \"icon\": \"text-field\", \"type\": \"input\", \"options\": {\"name\": \"input30722\", \"size\": \"\", \"type\": \"text\", \"label\": \"壓力(MP)\", \"hidden\": false, \"onBlur\": \"\", \"onFocus\": \"\", \"onInput\": \"\", \"disabled\": false, \"onChange\": \"\", \"readonly\": false, \"required\": true, \"clearable\": true, \"maxLength\": null, \"minLength\": null, \"onCreated\": \"\", \"onMounted\": \"\", \"buttonIcon\": \"custom-search\", \"labelAlign\": \"\", \"labelWidth\": null, \"onValidate\": \"\", \"prefixIcon\": \"\", \"suffixIcon\": \"\", \"validation\": \"\", \"columnWidth\": \"200px\", \"customClass\": [], \"labelHidden\": false, \"placeholder\": \"\", \"appendButton\": false, \"defaultValue\": \"\", \"labelTooltip\": null, \"requiredHint\": \"壓力不能為空\", \"showPassword\": false, \"showWordLimit\": false, \"labelIconClass\": null, \"validationHint\": \"\", \"labelIconPosition\": \"rear\", \"onAppendButtonClick\": \"\", \"appendButtonDisabled\": false}, \"formItemFlag\": true}]}, {\"id\": \"grid-col-71433\", \"icon\": \"grid-col\", \"type\": \"grid-col\", \"options\": {\"md\": 12, \"sm\": 12, \"xs\": 12, \"name\": \"gridCol71433\", \"pull\": 0, \"push\": 0, \"span\": 12, \"hidden\": false, \"offset\": 0, \"responsive\": false, \"customClass\": []}, \"category\": \"container\", \"internal\": true, \"widgetList\": [{\"id\": \"select11081\", \"key\": 31288, \"icon\": \"select-field\", \"type\": \"select\", \"options\": {\"name\": \"select11081\", \"size\": \"\", \"label\": \"材質(zhì)\", \"hidden\": false, \"onBlur\": \"\", \"remote\": false, \"onFocus\": \"\", \"disabled\": false, \"multiple\": false, \"onChange\": \"\", \"required\": true, \"clearable\": true, \"onCreated\": \"\", \"onMounted\": \"\", \"filterable\": true, \"labelAlign\": \"\", \"labelWidth\": null, \"onValidate\": \"\", \"validation\": \"\", \"allowCreate\": false, \"columnWidth\": \"200px\", \"customClass\": [], \"labelHidden\": false, \"optionItems\": [{\"label\": \"鑄鐵\", \"value\": 1}, {\"label\": \"不銹鋼\", \"value\": 2}, {\"label\": \"碳鋼\", \"value\": 3}, {\"label\": \"銅\", \"value\": 4}, {\"label\": \"其他\", \"value\": 5}], \"placeholder\": \"\", \"defaultValue\": \"\", \"labelTooltip\": null, \"requiredHint\": \"材質(zhì)不能為空\", \"multipleLimit\": 0, \"onRemoteQuery\": \"\", \"labelIconClass\": null, \"validationHint\": \"\", \"automaticDropdown\": false, \"labelIconPosition\": \"rear\"}, \"formItemFlag\": true}]}], \"icon\": \"grid\", \"type\": \"grid\", \"options\": {\"name\": \"grid40469\", \"gutter\": 12, \"hidden\": false, \"colHeight\": null, \"customClass\": []}, \"category\": \"container\"}, {\"id\": \"grid4823\", \"key\": 62462, \"cols\": [{\"id\": \"grid-col-24973\", \"icon\": \"grid-col\", \"type\": \"grid-col\", \"options\": {\"md\": 12, \"sm\": 12, \"xs\": 12, \"name\": \"gridCol24973\", \"pull\": 0, \"push\": 0, \"span\": 12, \"hidden\": false, \"offset\": 0, \"responsive\": false, \"customClass\": []}, \"category\": \"container\", \"internal\": true, \"widgetList\": [{\"id\": \"input21916\", \"key\": 28602, \"icon\": \"text-field\", \"type\": \"input\", \"options\": {\"name\": \"input21916\", \"size\": \"\", \"type\": \"text\", \"label\": \"其他屬性\", \"hidden\": false, \"onBlur\": \"\", \"onFocus\": \"\", \"onInput\": \"\", \"disabled\": false, \"onChange\": \"\", \"readonly\": false, \"required\": false, \"clearable\": true, \"maxLength\": null, \"minLength\": null, \"onCreated\": \"\", \"onMounted\": \"\", \"buttonIcon\": \"custom-search\", \"labelAlign\": \"\", \"labelWidth\": null, \"onValidate\": \"\", \"prefixIcon\": \"\", \"suffixIcon\": \"\", \"validation\": \"\", \"columnWidth\": \"400px\", \"customClass\": [], \"labelHidden\": false, \"placeholder\": \"\", \"appendButton\": false, \"defaultValue\": \"\", \"labelTooltip\": null, \"requiredHint\": \"\", \"showPassword\": false, \"showWordLimit\": false, \"labelIconClass\": null, \"validationHint\": \"\", \"labelIconPosition\": \"rear\", \"onAppendButtonClick\": \"\", \"appendButtonDisabled\": false}, \"formItemFlag\": true}]}], \"icon\": \"grid\", \"type\": \"grid\", \"options\": {\"name\": \"grid4823\", \"gutter\": 12, \"hidden\": false, \"colHeight\": null, \"customClass\": []}, \"category\": \"container\"}]}', '', 1709188741, 'G6', 1711434246, 1021100012, 1);
2、數(shù)據(jù)的查詢
在使用上面的sql腳本將數(shù)據(jù)插入到數(shù)據(jù)庫之后呢,我們怎么把頁面的表單給精準的查詢出來呢?實現(xiàn)我們最初的需求呢。這里就需要介紹一下在MySQL中的JSON數(shù)據(jù)的查詢問題。在MySQL5.7中關(guān)于JSON的方法參見其官網(wǎng)的定義:
Name | Description | Introduced | Deprecated |
---|---|---|---|
-> | Return value from JSON column after evaluating path; equivalent to JSON_EXTRACT(). | ||
->> | Return value from JSON column after evaluating path and unquoting the result; equivalent to JSON_UNQUOTE(JSON_EXTRACT()). | 5.7.13 | |
JSON_APPEND() | Append data to JSON document | Yes | |
JSON_ARRAY() | Create JSON array | ||
JSON_ARRAY_APPEND() | Append data to JSON document | ||
JSON_ARRAY_INSERT() | Insert into JSON array | ||
JSON_CONTAINS() | Whether JSON document contains specific object at path | ||
JSON_CONTAINS_PATH() | Whether JSON document contains any data at path | ||
JSON_DEPTH() | Maximum depth of JSON document | ||
JSON_EXTRACT() | Return data from JSON document | ||
JSON_INSERT() | Insert data into JSON document | ||
JSON_KEYS() | Array of keys from JSON document | ||
JSON_LENGTH() | Number of elements in JSON document | ||
JSON_MERGE() | Merge JSON documents, preserving duplicate keys. Deprecated synonym for JSON_MERGE_PRESERVE() | 5.7.22 | |
JSON_MERGE_PATCH() | Merge JSON documents, replacing values of duplicate keys | 5.7.22 | |
JSON_MERGE_PRESERVE() | Merge JSON documents, preserving duplicate keys | 5.7.22 | |
JSON_OBJECT() | Create JSON object | ||
JSON_PRETTY() | Print a JSON document in human-readable format | 5.7.22 | |
JSON_QUOTE() | Quote JSON document | ||
JSON_REMOVE() | Remove data from JSON document | ||
JSON_REPLACE() | Replace values in JSON document | ||
JSON_SEARCH() | Path to value within JSON document | ||
JSON_SET() | Insert data into JSON document | ||
JSON_STORAGE_SIZE() | Space used for storage of binary representation of a JSON document | 5.7.22 | |
JSON_TYPE() | Type of JSON value | ||
JSON_UNQUOTE() | Unquote JSON value | ||
JSON_VALID() | Whether JSON value is valid |
3、在5.7版本中進行JSON檢索
首先第一步查詢一下數(shù)據(jù)版本,在客戶端軟件中執(zhí)行以下sql:
-- 查看mysql 的服務(wù)器版本 SELECT VERSION(); 5.7.14-log
第二步、查詢當(dāng)前待提取的表單的選項的最大長度
-- 這里只能在mysql中使用一種折中的實現(xiàn)方案 -- 查出數(shù)組最大長度 SELECT MAX(JSON_LENGTH(JSON_EXTRACT(attr_config, CONCAT('$**.options')))) FROM ems_equipment_classification_attr where equip_class_id = '3'; 13
這里要查詢JSON_LENGTH的原因是因為,在當(dāng)前我這個版本的MYSQL中,如果要實現(xiàn)行列轉(zhuǎn)護轉(zhuǎn)換,只能使用一種折中的方式。通過上述的步驟求出待提取的目標(biāo)的長度,然后動態(tài)拼接參數(shù),實現(xiàn)數(shù)據(jù)轉(zhuǎn)成多行。這里直接給出最終拼接成的SQL,在得到這個SQL之前,我也是花了很長的時間進行實驗才找到這個方法,感謝前人提供的思路。
select tb.element -> '$[0].key' keystr,tb.element ->> '$[0].type' type, tb.element ->> '$[0].icon' icon, tb.element ->> '$[0].options.name' namestr, tb.element ->> '$[0].options.label' label, tb.element ->> '$[0].options.optionItems' optionItems, tb.element from ( SELECT JSON_EXTRACT(ta.json_val, CONCAT('$[', idx ,']')) AS element FROM ( SELECT JSON_TYPE( attr_config -> '$**.widgetList' ) type, attr_config -> '$**.widgetList' json_val,t.* FROM ems_equipment_classification_attr t WHERE JSON_TYPE( attr_config -> '$**.label' ) IS NOT NULL AND equip_class_id = '3' ) ta -- Inline table of sequential values to index into JSON array INNER JOIN ( SELECT 0 AS idx UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION select 6 union select 7 union select 8 -- 一直 UNION 到數(shù)組最大長度 - 1 ) AS indexes -- 排除元素數(shù)量比最大值要小導(dǎo)致的空項 WHERE JSON_EXTRACT(ta.json_val, CONCAT('$[', idx ,']')) IS NOT NULL ORDER BY idx ) tb where JSON_TYPE(tb.element ->'$**.label') IS NOT NULL;
請注意這里的1到8就是需要動態(tài)生成,結(jié)合mybatis框架,可以支持按傳入的參數(shù)進行生成。
查詢出來的結(jié)果如下所示:
43585 grid grid grid93809
90048 input text-field input36308 直徑(DN)
27039 select select-field select17890 制動方式 [{"label": "手動", "value": 1}, {"label": "電動", "value": 2}, {"label": "氣動", "value": "3"}, {"label": "液壓控制", "value": 4}, {"label": "其他", "value": 5}]
90048 input text-field input30722 壓力(MP)
31288 select select-field select11081 材質(zhì) [{"label": "鑄鐵", "value": 1}, {"label": "不銹鋼", "value": 2}, {"label": "碳鋼", "value": 3}, {"label": "銅", "value": 4}, {"label": "其他", "value": 5}]
28602 input text-field input21916 其他屬性
到此,在MySQL5.7下的查詢完全實現(xiàn)。剩下的參數(shù)匹配等,我們在系統(tǒng)重直接對應(yīng)節(jié)即可。
4、8.0后的優(yōu)化查詢
在mysql8.0之前,mysql沒有支持JSON_TABLE的用法,所以我們只用采用上面的這種處理辦法。如果您的項目環(huán)境用的是8.0的,那么可以直接使用JSON_TABLE的方法直接生成,更加簡單。各位如果有8.0的環(huán)境,可以按照以下sql進行實驗。
SELECT * FROM ems_equipment_classification_attr t CROSS JOIN JSON_TABLE( t.attr_config -> '$**.widgetList', '$[*]' COLUMNS( value VARCHAR(255) PATH '$[0].options.value', label VARCHAR(255) PATH '$[0].options.label', name VARCHAR(255) PATH '$[0].options.name', type VARCHAR(255) path '$[0].type', icon VARCHAR(255) path '$[0].icon', requiredHint VARCHAR(255) PATH '$[0].options.requiredHint', optionItems json path '$[0].options.optionItems' ) ) AS jt where t.equip_class_id = '3';
正常執(zhí)行的話可以得到以下的結(jié)果:
43585 grid grid grid93809
90048 input text-field input36308 直徑(DN)
27039 select select-field select17890 制動方式 [{"label": "手動", "value": 1}, {"label": "電動", "value": 2}, {"label": "氣動", "value": "3"}, {"label": "液壓控制", "value": 4}, {"label": "其他", "value": 5}]
90048 input text-field input30722 壓力(MP)
31288 select select-field select11081 材質(zhì) [{"label": "鑄鐵", "value": 1}, {"label": "不銹鋼", "value": 2}, {"label": "碳鋼", "value": 3}, {"label": "銅", "value": 4}, {"label": "其他", "value": 5}]
28602 input text-field input21916 其他屬性
基本上跟5.7的執(zhí)行結(jié)果差不太多。到此就完成了在MySQL中兩個版本的json數(shù)據(jù)的精準查詢的支持。希望對大家有所幫助。
三、總結(jié)
以上就是本文的主要內(nèi)容,本文重點講解如何在將設(shè)計好的動態(tài)表單信息進行提取,比如進行模板數(shù)據(jù)導(dǎo)入的時候,可以根據(jù)不同的表單類型,比如根據(jù)單行文字框的名字來動態(tài)設(shè)置值,也可以在導(dǎo)數(shù)數(shù)據(jù)時,知道將數(shù)據(jù)庫的性別一列保存的1和2翻譯成男和女這兩種屬性。這都需要我們精準的提取表單中的不同的信息,能精準提取表單的文本、類型、默認值域還有其他的表單元素的設(shè)置。通過本文,您可以了解如何正確的操作動態(tài)表單信息,同時了解如何從表單中查找表單元素。行文倉促,難免有不足之處,歡迎各位專家朋友批評指正,不甚感激。
參考資料:
到此這篇關(guān)于MySQL中實現(xiàn)動態(tài)表單中JSON元素精準匹配的方法示例的文章就介紹到這了,更多相關(guān)MySQL JSON元素精準匹配內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL用戶授權(quán)管理及白名單的實現(xiàn)
MySQL作為一種常用的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),在權(quán)限管理和用戶認證方面提供了豐富的功能和方案,本文主要介紹了MySQL用戶授權(quán)管理及白名單的實現(xiàn),感興趣的可以了解一下2023-09-09MySQL產(chǎn)生隨機數(shù)并連接字符串的方法示例
這篇文章主要介紹了MySQL產(chǎn)生隨機數(shù)并連接字符串的方法,簡單分析了相關(guān)函數(shù),并結(jié)合實例形式給出了相應(yīng)的SQL語句實現(xiàn)方法,需要的朋友可以參考下2017-05-05Navicat中新建MySQL數(shù)據(jù)庫與新建、修改、刪除數(shù)據(jù)表及刪除數(shù)據(jù)庫詳細操作方法
Navicat是一套快速、可靠并價格相當(dāng)便宜的數(shù)據(jù)庫管理工具,專為簡化數(shù)據(jù)庫的管理及降低系統(tǒng)管理成本而設(shè),這篇文章主要給大家介紹了關(guān)于Navicat中新建MySQL數(shù)據(jù)庫與新建、修改、刪除數(shù)據(jù)表及刪除數(shù)據(jù)庫詳細操作的相關(guān)資料,需要的朋友可以參考下2023-11-11Windows(x86,64bit)升級MySQL 5.7.17免安裝版的詳細教程
這篇文章主要介紹了Windows(x86,64bit)升級MySQL 5.7.17免安裝版的詳細教程,需要的朋友可以參考下2017-02-02MySQL數(shù)據(jù)表設(shè)計之自動增長的實現(xiàn)
本文主要介紹了MySQL數(shù)據(jù)表設(shè)計之自動增長的實現(xiàn),包括創(chuàng)建數(shù)據(jù)表時設(shè)置自動增長和修改數(shù)據(jù)表時添加自動增長,具有一定的參考價值,感興趣的可以了解一下2025-03-03