【專案問題總結】5:樹形結構節點的級聯刪除邏輯
問題描述:
改Bug改到機構型別管理模組的時候,有一個非常常見的問題出現,如下圖所示:
當使用者在進行刪除操作的時候,如果將樹形結構的中間節點刪除,整個頁面的資料就消失了,比如將上圖中的名稱為“學院”的這個節點刪除,那麼整個樹形結構的資料都沒了,這是一個很明顯的Bug。
問題分析:
對於這樣一個這麼明顯的Bug,什麼原因造成的?一開始在頁面進行操作的時候並不知道是哪裡出了問題,後來開啟資料庫對應的表結構才發現,這種樹形結構對應的資料庫表是一張自關聯表。當我在頁面將中間節點(非葉子節點)刪除之後,對照著資料庫檢視,發下該節點下的子節點並沒有被刪除。
找到了問題的關鍵,下面就要想辦法解決之。這是一個級聯刪除的情景,在刪除父節點的時候,其下所有的子節點也應該被刪除。之前使用過Hibernate,知道Hibernate的對映關係中有一個cascade屬性,其值有all、delete、save-update和none,它們各自的含義相信大家也都瞭解。其中delete表示在執行delete時,進行級聯操作,刪除和該物件關聯的物件。
那麼下面的問題是,該專案使用的ORM框架是不是支援級聯操作的設定呢?本專案所使用的ORM框架是EclipseLink + JPA,我一想完了,沒用過啊,接著去網上找相關的資料,看EclipseLink的級聯操作如何設定,發現資料很少,大都是英文的,而且也沒有找到如何設定類似於cascade屬性設定的內容,於是乎,我就開始想自己寫程式碼實現級聯刪除。
當我去分析程式碼的時候,發現底層的刪除方法並不是真正的delete,而是所謂的“軟刪除”,也就是在表結構中使用isDelete欄位來表示該資料記錄是否存在,此時我的內心是崩潰的,這玩意怎麼整啊?框架能解決級聯軟刪除的問題嗎?Maybe,but I don’t know。這更加堅定了我自己寫程式碼實現級聯刪除的決心。
問題解決:
解決辦法已經敲定,那麼剩下的就是coding了。要想實現級聯刪除(更新),就要引入“遞迴”的思想了,必須設計一個遞迴方法,來從樹形結構的上層節點向下進行遍歷,直到找到該分支的葉子節點,執行刪除之後,再一層一層的返回依次進行刪除,最終該節點以及其所有的子孫節點都刪除。下面我們來看具體的程式碼實現。
/**
* 更新節點資訊的isDelete欄位值,設定為1(0:存在 1:刪除)
*/
@Override
public boolean updateNodeLevel(String nodeid,String dataBaseName) {
String variable = "h.isDelete=:isDelete";
String condition = "where h.id ='" + nodeid + "'";
Map<Serializable,Serializable> map = new HashMap<Serializable, Serializable>();
map.put("isDelete", 1);
return institutionTypeEao.updateByConditionGeneric(variable, condition, dataBaseName, map, "h");
}
/**
* 遞迴刪除每個子節點
* @param nodeid
* @param dataBaseName
*/
private void recursionDelNode(String nodeid,String dataBaseName){
//查詢該節點的所有子節點
List<NodeLevel> nodeLevelList=findChildLevelsById(nodeid,dataBaseName);
//判斷該節點是否有子節點
if(nodeLevelList.size()>0){
//若有多個子節點,則遞迴遍歷所有的子節點
for(int i=0;i<nodeLevelList.size();i++){
//遞迴呼叫
recursionDelNode(nodeLevelList.get(i).getId(),dataBaseName);
}
}
//若沒有子節點則直接刪除
updateNodeLevel(nodeid,dataBaseName);
}
/**
* 刪除節點以及節點的所有子節點資訊
*/
@Override
public boolean deleteNodeLevel(String nodeId, String dataBaseName) {
boolean flag=true;
try{
recursionDelNode(nodeId,dataBaseName);
}catch(Exception e){
e.printStackTrace();
flag=false;
}
return flag;
}
其實,使用框架為我們封裝好的各種服務固然是方便快捷的,但是對於我們的能力提升是並沒有什麼益處的。最為一個程式設計師,不要求你能寫出多麼高大上的框架和演算法,但是基礎的東西還是需要我們去掌握的,知其然,知其所以然。
相關文章
- layui.tree樹形結構節點判定條件的刪除操作UI
- 【專案問題總結】4:修改操作的重複性驗證邏輯
- 架構-穩定性建設邏輯問題實戰總結架構
- 資料庫——查詢樹形結構某節點的所有子節點、所有父節點資料庫
- 微信小程式學習總結01:專案結構中增加業務邏輯目錄微信小程式
- 樹形結構
- vue專案問題總結Vue
- 在vue專案中使用樹形結構的穿梭框Vue
- 資料結構知識點--儲存結構與邏輯結構資料結構
- oracle的邏輯結構Oracle
- javascript樹形總結JavaScript
- PostgreSQL:邏輯結構SQL
- oracle 邏輯結構Oracle
- 檔案的邏輯結構、檔案目錄
- layui樹形結構UI
- java樹形結構Java
- 樹結構總結
- Android 多級樹形結構顯示Android
- [zt] Oracle的邏輯結構Oracle
- JN專案-觸發器級聯刪除觸發器
- vue專案中遇到的問題總結Vue
- 3:Oracle體系結構(邏輯結構)Oracle
- shared pool的物理結構和邏輯結構
- 七、基本資料結構(樹形結構)資料結構
- 樹形結構處理
- 企業級React專案的個人構建總結React
- 一類子樹問題的總結
- VUE 實現 Studio 管理後臺(七):樹形結構,檔案樹,節點樹共用一套程式碼 NodeTreeVue
- 線上支付邏輯漏洞總結
- 資料結構與演算法知識點總結(5)查詢樹資料結構演算法
- IC卡檔案系統的邏輯結構【轉】
- LayUI—tree樹形結構的使用UI
- 單節點主庫、邏輯備庫升級為RAC、物理備庫、邏輯備庫(5)
- leetcode----刪除連結串列中的節點LeetCode
- 資料結構中樹形結構簡介資料結構
- Oracle OCP(41):邏輯結構Oracle
- Oracle 邏輯結構簡介Oracle
- ATM-Shop專案結構樹