需求背景
前幾天有個任務,須要在系統中導入幾個excel文件,excel字段比較多(最少也有70來個字段,多的有170個字段),要的比較急,分給3個同事開始作。幾個同事憨憨的就開始根據excel文件建立表了(你們約定好,excel的b列字段對應db字段col_b,c字段對應col_c),而後實現導入導出功能了。忙的滿頭大汗,終於在下午弄出來了,此處應該有掌聲^_^java
需求痛點
悲劇發生了,需求變動了,原先的表有的廢棄了,有的字段變動了,還有新表來了,明天交付。一下哀嚎遍地,成妾作不到啊。。。算法
架構設計
那麼這個需求怎麼才能實現快速交付呢?咱們分析下 有哪些體力活:spring
- 因爲字段較多,建表sql,就算1個字段20s,中間一個不出錯20*170/60=56.7min 2.因爲使用easyExcel導入導出,相應的@ExcelProperty不少 3.需求不肯定,字段和表的常常變更 4.後臺邏輯雷同,導入都是先刪除再插入 解決思路:
- 幾分鐘寫個小程 序讀取excel,獲取表頭信息生成對應建表sql,須要花點時間寫個數字轉換成excel字母列的小算法
- 根據db的表結構生成對應文件,我是改造mybatis-generate來生成含有@ExcelProperty的bean 3.實現了1和2,天然不怕字段變更了,花幾分鐘時間從新生成下就ok了 4.代碼層面的優化下面再來具體分析
代碼層面的架構
解決了最大的體力勞動,代碼上面大量的重複仍是很不爽,改造前controller代碼相似:sql
try{ XXSer.importXXX }catch(Excepotion){ //錯誤信息處理 }catch(Excepotion1){ //錯誤信息處理 } return....
使用spring的統一異常處理,controller裏面只須要調用service的業務邏輯方法便可 改造前service代碼相似:mybatis
if(aaa==null){ throw new BizException("不能。。。") } 讀取excel文件 刪除原先記錄 插入原先記錄 插入日誌
觀察發現,各個service的邏輯能夠說是同樣的,基本上就是表名不同,這種體力活怎麼優化呢? spring提供的aop就是個很好的實現,能夠定義一個方法或者自定義註解,而後經過aop攔截實現相應功能。若是沒有使用spring,直接經過動態代理也能夠實現相似功能。無論用什麼方式實現,思想都是抽取公用邏輯,不須要滿篇ctrl+c,ctrl+v架構
後期優化
若是相似需求不少,能夠考慮作成1個功能,頁面導入1個excel文件,系統生成對應文件,複製到相應位置。甚至能夠更近一步,所有動態代理,反射生成對應代理類,經過傳入tablename和具體字段複用一個公用sql,新增一個表都無需重啓系統。性能
總結
- 用代碼來替代體力勞動
- 觀察找出公用邏輯,透過現象看本質,儘可能複用公用部分。
本文只是拿了一個需求場景來描述架構的思路,實際中會有不一樣的需求,例如每一個表有對應的業務邏輯,報表導入,查詢有較高的性能要求等等,不能生搬硬套。優化