Mysql里的数据:------+
| id | pid  | rootid | title          | cont           | pdate               |
sleaf |
+----+------+--------+----------------+----------------+---------------------+-
------+
|  1 |    0 |      1 | 蚂蚁大战大象   | 蚂蚁大战大象   | 2010-05-04 21:16:19 |
    1 |
|  2 |    1 |      1 | 大象被打趴下了 | 大象被打趴下了 | 2010-05-04 21:17:51 |
    1 |
|  3 |    2 |      1 | 蚂蚁也不好过   | 蚂蚁也不好过   | 2010-05-04 21:19:06 |
    0 |
|  4 |    2 |      1 | 瞎说           | 瞎说           | 2010-05-04 21:20:41 |
    1 |
|  5 |    4 |      1 | 没有瞎说       | 没有瞎说       | 2010-05-04 21:21:54 |
    0 |
|  6 |    1 |      1 | 怎么可能       | 怎么可能       | 2010-05-04 21:23:27 |
    1 |
|  7 |    6 |      1 | 怎么没有可能   | 怎么没有可能   | 2010-05-04 21:25:11 |
    0 |
|  8 |    6 |      1 | 可能性是很大的 | 可能性是很大的 | 2010-05-04 21:26:42 |
    0 |
|  9 |    2 |      1 | 大象进医院了   | 大象进医院了   | 2010-05-04 21:29:09 |
    1 |
| 10 |    9 |      1 | 护士是蚂蚁     | 护士是蚂蚁     | 2010-05-04 21:30:17 |
    0 |
+----+------+--------+----------------+----------------+---------------------+-
------+
错误代码:
package liufukun;
import java.sql.*;
public class ArticleTree {
     Connection conn=null;
     Statement stmt=null;
     ResultSet rs=null;
     int thisId=0;
     int thisLeaf=1;
     int thisLevel=1;
     public ArticleTree() {
      try{
        try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
conn=DriverManager.getConnection("jdbc:mysql://localhost/bbs?user=root&password=liufukun");
stmt=conn.createStatement();
     } catch(SQLException e) {
      e.printStackTrace();
     }
     }
    public void copeWith() {
     try{
 if(rs!=null) {
 rs.close();
 rs=null;
 }
 if(stmt!=null) {
stmt.close();
stmt=null;
 }
 if(conn!=null) {
 conn.close();
conn=null;
 }
     } catch(SQLException e) {
     e.printStackTrace();
     }
 }
     
     public void tree(int id,int level) {
      String s="";
      for(int i=1;i<level;i++) {
         s+="%%%%%%";
      }
      try {
rs=stmt.executeQuery("select * from article where pid="+id);
} catch (SQLException e) {
e.printStackTrace();
}
try {
while(rs.next()) {
System.out.println(s+rs.getString("cont"));
thisId=Integer.parseInt(rs.getString("id"));
thisLeaf=Integer.parseInt(rs.getString("isleaf"));
if(thisLeaf!=0) { 
 thisLevel=level+1;
 tree(thisId,thisLevel);
 }
}
} catch (SQLException e) {
e.printStackTrace();
}
     }
public static void main(String[] args) {
ArticleTree articleTree=new ArticleTree();
articleTree.tree(0, 1);
/*try{
articleTree.rs= articleTree.stmt.executeQuery("select * from article where pid=2");
while(articleTree.rs.next()) {
System.out.println(articleTree.rs.getString("cont"));

} catch(Exception e)  {
e.printStackTrace();
}*/
        articleTree.copeWith();
}
}
//执行结果是:
蚂蚁大战大象  
%%%%%%大象被打趴下了  
%%%%%%%%%%%%蚂蚁也不好过  
%%%%%%%%%%%%瞎说  
%%%%%%%%%%%%%%%%%%没有瞎说 
我另外写的一个执行正确的代码:package liufukun;
import java.sql.*;public class ArticleTree {
int thisId=0;
int thisLeaf=1;
int thisLevel=1;
private  void tree(int id,int level)  {
    Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
String s="";
for(int i=1;i<level;i++) {
s+="******";
}
try{
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
conn=DriverManager.getConnection("jdbc:mysql://localhost/bbs?user=root&password=liufukun");
} catch(SQLException e) {
e.printStackTrace();
}
try{
stmt=conn.createStatement();
rs=stmt.executeQuery("select * from article where pid="+id);
if(rs==null) {return;}//????????????????????????????????
    while(rs.next()) {
System.out.println(s+rs.getString("cont"));
    thisId=Integer.parseInt(rs.getString("id"));
    thisLeaf=Integer.parseInt(rs.getString("isleaf"));
    if(thisLeaf==1) {
     thisLevel=level+1;
       tree(thisId,thisLevel);
 }
}
    try{
    if(rs!=null) {
     rs.close();
     rs=null;
     }
     if(stmt!=null) {
     stmt.close();
     stmt=null;
     }
     if(conn!=null) {
     conn.close();
     conn=null;
     }
    } catch(SQLException e) {
     e.printStackTrace();
    }
} catch(SQLException e) {
e.printStackTrace();

/*finally {
try{
if(rs!=null) {
rs.close();
rs=null;
}
if(stmt!=null) {
stmt.close();
stmt=null;
}
if(conn!=null){
conn.close();
conn=null;
}
} catch(SQLException e) {
e.printStackTrace();
}
}*/
}
public static void main(String[] args) {
ArticleTree articleTree=new ArticleTree();
articleTree.tree(0,1);
}
  }
//正确执行的结果:
蚂蚁大战大象
******大象被打趴下了
************蚂蚁也不好过
************瞎说
******************没有瞎说
************大象进医院了
******************护士是蚂蚁
******怎么可能
************怎么没有可能
************可能性是很大的
正确的那代码首先写的,后优化时有了错误代码,望高手帮我找找错误的代码原因?

解决方案 »

  1.   

    if(thisLeaf!=0) { 
    thisLevel=level+1;
    tree(thisId,thisLevel);
    }凡是不是子节点就递归了。但是递归后,回到子节点时,thisLevel没有重新置为1。
    加上
    else{
    thisLevel=1;
    }
    试试看?另外两个成员变量是否需要重置没仔细看。
      

  2.   

    非常感谢你的指教,不过不是那里有问题,我试过了,问题是在于当pid==2时程序为何只从数据库取到2个返回值,本来应该取到3个值的呀像下面的那个正确程序一样(蚂蚁也不好过,瞎说,大象进医院了),
    不知道是什么原因,下面的程序和上面的思路完全是一样的,但结果却不同?
      

  3.   

    错误代码改正:
    package liufukun;
    import java.sql.*;
    public class ArticleTree {
         Connection conn=null;
         int thisId=0;
         int thisLeaf=1;
         int thisLevel=1;
         public ArticleTree() {
          try{
            try {
    Class.forName("com.mysql.jdbc.Driver");
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    }
    conn=DriverManager.getConnection("jdbc:mysql://localhost/bbs?user=root&password=liufukun");
         } catch(SQLException e) {
          e.printStackTrace();
         }
         }
        public void copeWith() {
         try{
     if(conn!=null) {
     conn.close();
    conn=null;
     }
         } catch(SQLException e) {
         e.printStackTrace();
         }
     }
         
         public void tree(int id,int level) {
          Statement stmt=null;
          ResultSet rs=null;
          String s="";
          for(int i=1;i<thisLevel;i++) {
             s+="%%%%%%";
          }
          try {
         stmt=conn.createStatement();
    rs=stmt.executeQuery("select * from article where pid="+id);
    } catch (SQLException e) {
    e.printStackTrace();
    }
    try {
    while(rs.next()) {
    System.out.println(s+rs.getString("cont"));
    thisId=rs.getInt("id");
    thisLeaf=rs.getInt("isleaf");
    if(thisLeaf!=0) { 
     thisLevel+=1;
     tree(thisId,thisLevel);
     }
    }
    try {
    if(stmt!=null) {
    stmt.close();
    stmt=null;
    }
    if(rs!=null) {
    rs.close();
    rs=null;
    }
    } catch(Exception e) {
    e.printStackTrace();
    }
    } catch (SQLException e) {
    e.printStackTrace();
    }
         }
    public static void main(String[] args) {
    ArticleTree articleTree=new ArticleTree();
    articleTree.tree(0,1);
            articleTree.copeWith();
    }
    }
    错误原因分析:
    在递归中因为Statement stmt和ResultSet rs被创建为成员变量,因此他们都分别只有一份,在递归调用中当他们从数据库得到新的数据时,就会把旧的数据给抛弃(原数据被替换),所以原来取到的一部分数据就会丢失,出现上面的错误情况,所以改正后把Statement stmt和ResultSet rs都创建为局部变量,可以保存递归中各部分的值就对了.O(∩_∩)O~
    总结:jdbc连接数据库时,类似用到递归的情况下,Connection conn可创建为成员变量,Statement stmt和ResultSet不宜创建为成员变量(创建为局部变量).