[TOC] # 1. 为什么要翻新 ## 1.1. 代码可维护性 mes的代码,采用的java拼装sql,然后sql非常复杂,大量无效流程分支的情况 例如下面:一个看似简单的查询 ```java public CoreReturnObject doQueryData(ArrayList list,String[] arr,String strPlanSql,String bathYear) { String sql = CoreXmlSqlParsersFactory.getSql("FrmReportOutput.doQueryData").replace("#COLUMNS#", list.get(0)); sql +=CoreConverter.toSqlConditionString("t.STORAGE_NO", arr); sql = sql.replace("#CONDITIONS#", list.get(1)); sql = sql + list.get(2); sql += " )F1)F"; sql += " LEFT JOIN (SELECT SUM(NVL(T1.CUT_WEIGHT,'0')*NVL(T1.REAL_INDOUBLE_NUM,'0')) CUT_WEIGHT,#JUDGE_STOVE_NO1# T1.HEAT_PLAN_NO,T1.PRO_PLAN_ID,T1.GX_PLAN_NO FROM PLN_ZY_ZG_C T1,MIL_PLAN S1 WHERE T1.HEAT_PLAN_NO = S1.ID AND S1.BACK_PLAN_FLAG = '0'" + " AND S1.BACK_SLAB_FLAG = '0' AND T1.CUT_TARGET = '返废' #BATH_YEAR# GROUP BY #JUDGE_STOVE_NO1# T1.HEAT_PLAN_NO,T1.PRO_PLAN_ID,T1.GX_PLAN_NO) D ON F.PRO_PLAN_ID_ZG = D.PRO_PLAN_ID AND F.GX_PLAN_NO_ZG = D.GX_PLAN_NO #DD# "; sql += " AND F.OUTSTOCK_TYPE_CODE = '800801' AND F.RK =1"; if(!strPlanSql.equals("")) { sql = sql.replace("#DD#", strPlanSql).replace("#JUDGE_STOVE_NO#", "JUDGE_STOVE_NO,").replace("#JUDGE_STOVE_NO1#", "T1.JUDGE_STOVE_NO,"); }else { sql = sql.replace("#DD#", "").replace("#JUDGE_STOVE_NO#", "").replace("#JUDGE_STOVE_NO1#", ""); } if(!bathYear.equals("")) { sql = sql.replace("#BATH_YEAR#", " AND S1.BAL_YEAR_MONTH = '"+bathYear+"'"); }else { sql = sql.replace("#BATH_YEAR#", ""); } return this.getData(sql); } ``` 存在以下问题 1. 参数全装list请求里。 2. 部分sql由前端告知(存在严重的注入风险) 3. 前端后端采用信任方式(不验证身份) 4. 在xml里面另外又维护了大段sql,任何一个修改需要 从3个地方结合sql才能知道在干嘛 5. \#号占位符,风险极高 6. 很随意就星星分组查询 例如下面:一个看似简单的查询对应的sql.xml部分 ```sql select #columns#, DECODE(T1.IS_DEALER, '0', '自用', '1', '双经销', '2', '来料加工','3','定销订购') IS_DEALER, DECODE(T1.BACK_FLAG, '0', '正常坯', '1', '回炉坯','2','套尺坯') BACK_FLAG, MAX(S1.PLAN_TIME_B) PLAN_TIME_B, T2.LOCATION_NAME, T2.LARY_NO, T2.STORAGE_NO, (SELECT T3.STORAGE_NAME FROM YDM_BS_STORAGE T3 WHERE T3.STORAGE_NO = T2.STORAGE_NO) STORAGE_NAME, T1.PRODUCT_FLAG, T1.MAT_STATUS, T1.STOVE_NO, T1.JUDGE_STOVE_NO, T1.JUDGE_STOVE_NO_LG, T1.SOURE_NAME, T1.MATERIAL_NAME, T1.GRADENAME, S1.ORDER_NO || '/' || S1.ORDER_SEQ AS ORDER_NO, T1.DIMATER, T1.ACT_LEN, T1.FIX_NUM, T1.FIX_LEN, DECODE(T1.QCM_STAUS, '00', '合格', '11', '待处理', '22', '废品') QCM_STAUS, T1.PLINE_NAME, T1.BELONG_NAME, MAX(TO_CHAR(T1.INSTOCK_TIME, 'YYYY-MM-DD HH24:MI:SS')) INSTOCK_TIME, T1.MEMO, T1.MEMO MEMO2, (SELECT T2.BASENAME FROM COM_BASE_INFO T2 WHERE T2.BASECODE = T1.JUDGE_RESULT_CODE) JUDGE_RESULT_CODE, MAX((SELECT S1.PLINE_NAME FROM PLN_ORDER_ZG_S S1 WHERE S1.PRO_PLAN_ID = T1.PRO_PLAN_ID_ZG AND S1.GX_PLAN_NO = T1.GX_PLAN_NO_ZG)) PLINE_NAME_NEXT, sum(T1.ACT_COUNT) as ACT_COUNT, sum(T1.ACT_WEIGHT) as ACT_WEIGHT, T1.MNG_LOCK_FLAG FROM MAT_GP_M T1 LEFT JOIN YDM_GP_BUTTRESS T2 on T1.MAT_NO = T2.MAT_NO LEFT JOIN YDM_BS_STORAGE S ON S.STORAGE_NO = T2.STORAGE_NO LEFT JOIN PLN_ORDER_ZG_S S1 ON T1.PRO_PLAN_ID_ZG = S1.PRO_PLAN_ID AND T1.GX_PLAN_NO_ZG = S1.GX_PLAN_NO WHERE T1.MAT_NO = T2.MAT_NO AND T1.IS_SETFOOT = '0' #something# group by T1.IS_DEALER, T1.BACK_FLAG, T2.LOCATION_NAME, T2.LARY_NO, T2.STORAGE_NO, T1.PRODUCT_FLAG, T1.MAT_STATUS, T1.STOVE_NO, T1.JUDGE_STOVE_NO, T1.JUDGE_STOVE_NO_LG, T1.SOURE_NAME, T1.MATERIAL_NAME, T1.GRADENAME, S1.ORDER_NO, S1.ORDER_SEQ, T1.DIMATER, T1.ACT_LEN, T1.FIX_NUM, T1.FIX_LEN, T1.QCM_STAUS, T1.PLINE_NAME, T1.BELONG_NAME, T1.MEMO, T1.JUDGE_RESULT_CODE, T1.MNG_LOCK_FLAG ``` 存在以下问题 1. 字段随意转码 (正确做法是在java中转换,索引之敌) 2. 随意的子查询 (在开发中是大忌) 3. 随意的分组查询(分组查询不允许用在业务模块上) 4. 多张表查询,应该尽量采用主表查询,从表拼装,多次查询的方式,这里为了省事一锅炖。 5. 存在大量魔法占位符 \#column#,#something# 之类,难以理解 (带来了天量的维护困难) ## 1.2. 并发及带来的相关灾难 #### 1.2.1 概念     事务         一件事情,不管多少步骤,要么做完,要么不做,不允许出现中间状态 > 例如: > > 小明给小方银行转账。步骤如下: > 1、小明,账上扣掉1块 > > 2、小明流水上增加一条支出信息 > > 3、小方,账上增加1块 > > 4、小方流水上增加一条收入信息          如果不带事务,那么中间状态不能是每方都能接受的 所以,我们在实际工作中带上事务 > 1、先冻结小明那条数据(其他人不能写或者读(不包括脏读)) > > 2、小明zhangs > > 2、流水表写入2条可回退事务插入 > > 3、冻结小方的那条数据(其他人不能读或者写)     事务死锁 1. 暴力解锁 2. 并发 3. 串行 4. 并发及带来的相关灾难 5. 项目健壮的重要性 6. 翻新发现问题并带来可靠维护文档 7. 可扩展开发性 8. 翻新步骤 9. 怎么保证翻新是可靠的,而不是带来新问题翻新步骤 10. 施工进度怎么控制 11. 旧系统下线的时机 12. 甲方操作人员需要配合做什么 13. 旧系统产生的历史错误数据如何处理 14. 告警中台推销