The tree structure being rendered. This article removes the tree structure from any node. Provide solutions
In the diagram, the leaf nodes are not included in the other nodes . Other nodes are the parent node , which is not the leaf node .
A knowledge point of this article:
(1) Recursive invocation:
because the level of the node to be deleted is uncertain, it is assumed that the leaf node can directly get the ID directly deleted, such as: Beijing TCM Hospital, North China area. Assuming that the node to be deleted is a parent node , you need to continue to query down, then iterate through its child nodes , and then delete them from the bottom up ., such as ' North China '. so we use recursive calls.
(2) guarantee the atomicity of the transaction
If the node to be deleted is ' North China '. is equivalent to delete 3 information (North China, Beijing, Peking Chinese Medicine Hospital). It is common to think that deleting multiple data at the same time is atomic.
Delete 100 messages, equivalent to a transaction. or delete them together. Either is not deleted.
transaction control, manifested in two aspects: one is the recursive deletion process using a connection (at the same time to prevent recursive loop calls resulting in connection efficiency is not high). There is also a setting for manual commit.
(3) exception is throws? Or a catch?
Main Method Delclientorr egion uses try...catch......finally to print the error message in the stack. The method that is called in the Main method. such as: Recursiondelnode, GetChildren, Modifyisleaffield. are private only for method internal calls. At the same time, the exception is thrown with throws sqlexception instead of catch catch.
This is because if the inner part of the GetChildren is catch error, the stack information is printed. So the upper layer doesn't know it's wrong. Therefore, the transaction is not rolled back.
It is therefore recommended to throw an exception inside the throws SQLException, external use catch exception try Catch
(4) Several design methods of trees
1) without redundant fields, ID primary key, PID parent node primary key
2) with redundant fields. ID, PID, isleaf is a leaf, childrencount the number of child nodes
3) adopts fixed string 0010001
00 All Distributors
01 North China Area
001 Beijing
0001 Beijing TCM Hospital
(This database design uses: ID primary key, PID parent node primary key, Is_leaf is leaf node)
(5) Business logic analysis, if you want to delete the node for ' Beijing '
1) Save the parent node object. That is: Get the ID of ' Beijing ' parent node ' North region '.
2) Delete Tree nodes recursively. That is: delete ' Beijing ' at the same time also want to delete their children knot Point ' Peking Chinese Medicine Hospital '.
The order of deletion is also required, first delete the child, then delete the father. That is, first remove the ' Beijing TCM Hospital '. After deleting ' Beijing '. This is reflected in the recursive code.
3) If there are no child nodes under the parent node , then the leaf node is changed.
That is, suppose ' north China ' has no children. You need to set ' north China ' as the leaf node .
The two-part code is as follows:
Package Com.bjpowernode.drp.basedata.manager;import Java.sql.connection;import Java.sql.preparedstatement;import Java.sql.resultset;import Java.sql.sqlexception;import Com.bjpowernode.drp.basedata.domain.aimclient;import Com.bjpowernode.drp.basedata.domain.client;import Com.bjpowernode.drp.util.constants;import Com.bjpowernode.drp.util.dbutil;import Com.bjpowernode.drp.util.idgenerator;import Com.bjpowernode.drp.util.pagemodel;import com.bjpowernode.drp.util.datadict.domain.clientlevel;/** * Implemented in single case * @ Author Administrator * */public class Clientmanager {private static Clientmanager instance = new Clientmanager ();p rivate C Lientmanager () {}public static Clientmanager getinstance () {return instance;} /** * Delete reseller or region * @param id */public void delclientorregion (int id) {Connection conn = null;try {conn = Dbutil.getconnectio n ();//manual control of Transaction Open dbutil.begintransaction (conn);//Save parent Node Object Client CurrentNode = Findclientorregionbyid (ID);// Recursively delete the tree node Recursiondelnode (conn, id);//Assume that there are no child nodes under the parent node if (GetChildren (conn, Currentnode.getpid ()) = = 0) {//change to Leaf Modifyisleaffield (conn, Currentnode.getpid (), constants.yes);} Commit TRANSACTION dbutil.committransaction (conn);} catch (Exception e) {//If an error occurs, print the stack information e.printstacktrace ();//Transaction rollback DBUTIL.ROLLBACKTRANSACTION (conn);} finally {//transaction reset Dbutil.resetconnection (conn);//Close database connection dbutil.close (conn);}} /** * Recursive DELETE * @param conn * @param id */private void Recursiondelnode (Connection conn, int id) throws SQLException {//by str ing sql = "SELECT * from T_client where pid=?"
"; PreparedStatement pstmt = null; ResultSet rs = null;try {conn = dbutil.getconnection ();p stmt = conn.preparestatement (sql);p Stmt.setint (1, id); rs = pstmt. ExecuteQuery (); while (Rs.next ()) {//assumes no leaf node. Then recursively call if (Constants.NO.equals (rs.getstring ("Is_leaf"))) {Recursiondelnode (conn, rs.getint ("id"));} Suppose it is a leaf node. Delete Delnode (conn, rs.getint ("id") directly);} Delete itself Delnode (conn, id);} Finally {Dbutil.close (RS);D butil.close (pstmt);}} /** * The number of children who get the specified node * @param conn * @param ID * @return */private int GetChildren (Connection conn, int id) throws Sqlexcepti The on {//sql statement is inferred from the number of child PID, is the leaf node string sql = "SELECT COUNT (*) as C from T_client where pid=?"; PreparedStatement pstmt = null; ResultSet rs = Null;int count = 0; try {conn = dbutil.getconnection ();p stmt = conn.preparestatement (sql);p Stmt.setint (1, id); rs = Pstmt.executequery (); Rs.next (); count = Rs.getint ("C");} Finally {Dbutil.close (RS);D butil.close (pstmt);} return count;} /** * Change isleaf field * @param conn * @param ID * @param leaf y/n */private void ModifyisleaffIeld (Connection conn, int id, String leaf) throws SQLException {//Assuming that the parent node of the node to be deleted has no other child node, then set to leaf state String sql = "Update T_clie NT set is_leaf=?
where id=?
"; PreparedStatement pstmt = null;try {conn = dbutil.getconnection ();p stmt = conn.preparestatement (sql);p stmt.setstring (1 , leaf);p Stmt.setint (2, id);p stmt.executeupdate ();} finally {dbutil.close (pstmt);}}}
Copyright notice: This article blog original article. Blogs, without consent, may not be reproduced.
"DRP" Delete the recursive tree operation