【項目問題總結】4:修改操作的重復性驗證邏輯


問題描述:

        在做基礎系統的Bug調試及修改的過程中,遇到了一個很奇怪的問題:在進行記錄的修改操作時,如下圖所示,


        理論上層次名稱和備注都是可以隨意修改的,但是如果我只是修改備注,對名稱不做任何的改動(或者是只是點開修改的彈出框,不做任何改動),點擊確定進行提交,總是彈出層次名稱重復的提示,導致修改失敗。

問題分析:

        經過各種測試,發現問題就出在這個名稱是否重復的判斷邏輯上,打開代碼進行查看,找到驗證層次名稱是否重復的代碼,如下所示:

public String validateLevelName(String levelName, String dataBaseName)
throws Exception {
Map<Serializable, Serializable> map = new HashMap<Serializable, Serializable>();
List<SchoolLevel> classlist = new ArrayList<SchoolLevel>();
String result;
classlist = schoolLevelBean.queryLevelNodeByName(levelName,dataBaseName<span style="font-family: Arial, Helvetica, sans-serif;"> );</span>
if (classlist == null || classlist.isEmpty()) {
// 無重復數據
result = "0";
} else {
// 有重復數據
result = "1";
}
return result;
}

        其調用的queryLevelNodeByName  方法如下

<span style="font-size:18px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"></span><pre name="code" class="java">public List<SchoolLevel> queryLevelNodeByName(String condition,
String dataBase) {

String hql = "from SchoolLevel h where h.levelName=:levelName and h.isDelete=0";
Map map = new HashMap();
map.put("levelName", condition);


// 調用底層 Hql查詢方法
return schoolLevelEao.queryByHql(hql, map, dataBase);
}

       從上面的代碼可以看到,判斷名稱是否重復的方法中只是根據名稱進行了查詢,判斷返回結果是否為空,即得出是否重復的結論,這個邏輯是不對的,為什么這么說呢?因為既然是修改操作,那么加載出來的這條記錄在數據庫中是存在的,然后用已經存在的名稱作為參數去數據庫進行查詢,結果肯定能查到至少一條,而查詢結果返回的數據就是頁面加載出來的那條記錄,以這樣的邏輯去進行判斷是否重復,其結果將永遠是“對不起,層次名稱已經存在,請返回修改!”。 

        怎么辦呢?最開始的想法是,既然是修改那么沒必要進行重復判斷了,只有在添加的時候,進行重復性判斷即可。可是修改代碼之后,發現還是不行,上述問題是沒了,又出來新的問題,出現了重復記錄,因為沒有進行重復性校驗,名稱可以肆無忌憚的重復了,回頭一想這方法真是too young too simple!

      后來才開始認真的尋找解決辦法,其核心問題是在進行重復性校驗的時候,將要修改的這條記錄本身排除即可。如何排除呢?我想到的有兩種思路,一種是在查詢語句上進行修改,在查詢條件上添加“id <> 要修改記錄的id”。另一種是,在查詢結果中將被修改的記錄排除,如果排除提交的記錄,查詢結果集還有記錄,那就證明和其自身除外的其他記錄的名稱重復了。

問題解決:

        思路有了,那么就着手開始修改代碼邏輯吧,先嘗試了第一種辦,修改查詢的JPQL語句,因為對JPQL語句不怎么熟悉,雖然類似於HQL,但是還是還是有些區別,我知道第一種方法簡單,但是沒有去深究,最后也沒成功。因此就改用第二種方法進行實現,經過了反復的測試和修改,終於是成功了,其代碼如下:

public String validateLevelName(String levelName,String levelID, String dataBaseName)
throws Exception {

Map<Serializable, Serializable> map = new HashMap<Serializable, Serializable>();
List<SchoolLevel> levelIdList = new ArrayList<SchoolLevel>();
List<SchoolLevel> classlist = new ArrayList<SchoolLevel>();
String result = "";
//根據提交的Id進行查詢
levelIdList = schoolLevelBean.queryLevelIDByHql(levelID, dataBaseName);
//根據提交的名稱進行查詢
classlist = schoolLevelBean.queryLevelNameByHql(levelName,dataBaseName);//classlist: 0 1

//根據Id查詢的記錄條數大於0是修改的重復判斷邏輯,否則就是添加的判斷邏輯
if(levelIdList.size()>0){ //修改的判斷邏輯
//同一Id下,如果提交的名稱和數據庫查詢出來的名稱相同,則不重復
if(levelIdList.get(0).getLevelName().equals(levelName)){
result="0";
}else{
//如果名稱做了改動,則將按名稱查詢的結果中的記錄本身排除
for(int i=0;i<classlist.size();i++){
if (classlist.get(i).getId()==levelID) {
classlist.remove(i);
}
}
//判斷移除其自身之后的記錄條數是否為0
if (classlist.size()==0) { //若為0,則不重復
result = "0";
} else { //否則重復
result = "1";
}
}

}else{ //添加的判斷邏輯
if(classlist.size()>0){
result="1";

}else{
result="0";
}
}


return result;
}

        因為添加和修改的名稱是否重復都要用這個函數,因此就將兩者判斷邏輯放在了一起,有些許繁瑣。雖然我實現了功能效果,但是心里明白這種實現還可以再優化,並且這種絕不是最優的實現方案,希望大家有好的解決方案可以給我留言,不勝感激。


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com