当前位置:网站首页>記一個基於JEECG-BOOT的比較複雜的增删改功能的實現

記一個基於JEECG-BOOT的比較複雜的增删改功能的實現

2022-07-06 06:21:00 瀚嶽-諸葛弩

做了分布式數據庫,跨庫調字典數據,多錶增删改,需要存冗餘字段,界面如下:

需求:

(1)list頁面可以複用

(2)增、删自定義頁面完成

1、JEECG-BOOT生成的前端頁面的理解

(1)混入脚本

前端自定義頁面List是列錶頁無疑,但是裏面一些方法、函數並沒有出現,是因為JEECG為了前端代碼簡單,進行了混入封裝,主要包括兩個混入脚本:@/utils/mixin和@/mixins/JeecgListMixin

(2)J-modal

此外,增加、删除,JEECG-BOOT在ant-design-vue的a-modal基礎上進行了修改,故:所有的彈出窗口通過插槽實現,如下:

跳轉到DeviceModal.vue再看:

DeviceModal.vue頁面不需要做其它修改。所有代碼非必要均可保持與生成時的一致。

通過上圖,可以完成默認頁面的替換

2、跨庫訪問數據

JEECG當中雖然用的是微服務方式,但是數據庫依然沒有分開。這能够很好地延續SOA的開發思想。所以,在開發過程中需要對數據庫進行分布式處理。配合nacos的在線配置,實現不同應用訪問不同數據庫。

(1)數據庫的設置

從上圖可以看出,每一個子系統均是獨立的數據庫,這樣的好處很多,一是降低耦合(庫錶分離),二是提高系統的健壯性(一個庫出問題或卡死,不影響其他業務系統運行),三是提高系統的性能(實現分布式)

(2)在nacos中做好配置

記住springboot的配置加載順序:

讀取優先級:bootstrap.yml(本地) > application.yml (全局共用,即:test/dev/prod通用)> application-dev.yml > order-service.yaml >order-service-dev.yaml

作用優先級:與上面順序相反,即:最後讀取的覆蓋前面讀取的配置

具體應用與哪一個nacos配置相關聯,在start模塊中的bootstrap.yml配置中指定,如下圖:

這是官方推薦的做法,理論上可以全部配置到本地,或者配置到nacos,具體為什麼這麼做,還沒有深入研究,有待進一步學習。

3、功能實現

(1)通過視圖實現數據庫的跨庫數據讀取共享

上文已述,JEECG-BOOT雖然做了微服務,但在數據庫端依然是單體數據庫,所以其生成的代碼、控件,均是從boot庫中提取數據(默認控件讀數據在boot),而我們在其基礎之上進行了數據庫的分布式設計(寫數據在具體業務庫),雖然可以完全拋弃jeecg-boot的生成代碼,自定義各種控件實現完全的分庫目的,但是工作量比較大,在時間比較緊張的情况下沒有必要(後續可修改jeecg-boot底層,使生成代碼也滿足自身個性化需要)。

為了符合jeecg-boot的默認讀需求,非常簡單,通過視圖跨庫共享數據即可,以下圖的device錶為例,在jeecg的boot庫中,只需按:select * from hanlin_product.device生成一個名為device的視圖即可。

(2)自定義多錶實體類,滿足反序列化需求

這次實現的功能如下圖所示:

這是一個典型的“1對多”,主附錶的插入。

JEECG並沒有提供很好的方式實現這種高度定制化的功能。所以前後端需要根據交互設計重新開發。

首先,Jeecg的反序列化封裝的很好,很方便,比JQuery中直接用json2來的簡單,與所有的反序列化思路一致:先建立實體類,再進行反序列化。故後端代碼在JEECG生成的基礎之上做如下構建:

此處,個人建議是建立一個多錶的包,將所有涉及多錶的實體全部放在此文件夾,方便運維和管理。如上圖中,所建立的包名為:multiTable

其次,建立多錶的後端操作,依然基於jeecg生成的代碼即可,編寫非常高效、簡單

這裏需要注意的是:jeecg生成的saveBatch操作(jeecg也是通過mybatis-plus生成的代碼)並不是真正意義上的批量保存,在大並發寫入時存在效率瓶頸。在小批量內容寫入時沒有問題,一旦並發過高,要用redis+mq突破瓶頸(這個後面再說,要自己寫)。

(3)前端代碼,以及前後端調用

先看前端的data,注釋如

data() {
  return {
    showPopMsg: false,//控制彈出窗口
    deviceId:'',//當前設備id,增加的時候默認分配guid,編輯的時候是當前編輯的記錄的id
    model: {},//沿用生成代碼,放的是當前錶的實體,即:各種錶屬性以model.xx存在
    labelCol: {
      xs: { span: 24 },
      sm: { span: 5 }
    },
    wrapperCol: {
      xs: { span: 24 },
      sm: { span: 16 }
    },
    confirmLoading: false,//是否提示正在加載,大批量數據操作時使用
    validatorRules: {},
    url: {
      add: '/jeecg-product/deviceMultiTable/saveWhole',
      edit: '/jeecg-product/deviceMultiTable/editWhole',
      queryById: '/jeecg-product/device/device/queryById'
    },//編輯、删除的後端controller接口地址
    columns: [
      {
        title: '指標類型',
        dataIndex: 'itemTypeId',
        key: 'itemTypeId',
        width: 80,
        scopedSlots: { customRender: 'itemTypeId' }
      },
      {
        title: '指標名稱',
        dataIndex: 'itemName',
        key: 'itemName',
        width: 120,
        scopedSlots: { customRender: 'itemName' }
      },
      {
        title: '顯示類型',
        dataIndex: 'dataShowingTypeId',
        key: 'dataShowingTypeId',
        width: 80,
        scopedSlots: { customRender: 'dataShowingTypeId' }
      },
      {
        title: '默認值',
        dataIndex: 'defaultValue',
        key: 'defaultValue',
        width: 80,
        scopedSlots: { customRender: 'defaultValue' }
      },
      { title: '單比特', dataIndex: 'unit', key: 'unit', width: 80, scopedSlots: { customRender: 'unit' } },
      {
        title: 'PLC地址',
        dataIndex: 'plcPlace',
        key: 'plcPlace',
        width: 80,
        scopedSlots: { customRender: 'plcPlace' }
      },
      {
        title: 'PLC數據類型',
        dataIndex: 'plcType',
        key: 'plcType',
        width: 100,
        scopedSlots: { customRender: 'plcType' }
      },
      {
        title: '是否重點觀測',
        dataIndex: 'isObservingItem',
        key: 'isObservingItem',
        width: 80,
        scopedSlots: { customRender: 'isObservingItem' }
      },
      {
        title: '是否維修監控',
        dataIndex: 'isMaintainingItem',
        key: 'isMaintainingItem',
        width: 80,
        scopedSlots: { customRender: 'isMaintainingItem' }
      },
      {
        dataIndex: 'oper',
        key: 'oper',
        width: 80,
        scopedSlots: { customRender: 'oper' },
        slots: { title: 'operTitle' }
      }
    ],//list列錶的字段
    deviceItemData: [],//自定義屬性,用於批量生成的內容
    selectedDeviceTypeId: ''//自定義屬性,用於保存自定義控件的值
  }
},

Methods代碼不一一展示(具體可看附件)

此處須注意的是submitForm()的修改:

4、改進思路

(1)saveBatch在大並發過程中可以提供真正的批量保存實現,也可通過redis+mq的方式穩定寫入數據庫(避免數據庫的“寫”阻塞),現mybatis-plus生成的代碼是“循環+插入”,大並發時肯定存在寫瓶頸。

(2)數據庫在分布式的基礎上,再次進行讀寫分離,可大大提高並發效率

(3)前端代碼雖然完成了功能,但寫的比較稀碎,不利於維護,可在現有代碼基礎上做好封裝,包括js封裝和單文件組件封裝。

原网站

版权声明
本文为[瀚嶽-諸葛弩]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/187/202207060619394928.html