无限级分类

最近在弄一个无限级的分类,上网搜了很多资料,感觉都不是很适用,仔细研究了下递归,并参考了老师的程序,终于弄出了点眉目,写出来和大家分享下,直接从项目里面拷出代码,稍做了点修改。
第一次在javaeye上写原创,不足之处请大家谅解。

数据库表的设计
数据库名为:business
表名为:news_class     //新闻分类表

为简化说明,只写了3个字段,分别为:
1、newsclass_id       //分类ID,int 类型
2、newsclass_parentid // 父ID,int 类型,这是分级关键,比如A的ID为B的父ID,说明A是B的父
                                              分类,以次类推,可以一级一级往下无限增长
                           
3、newsclass_title    //分类的标题,varchar类型


插入20条记录
+--------------+--------------------+-----------------+
| newsclass_id | newsclass_parentid | newsclass_title |
+--------------+--------------------+-----------------+
|            1 |                  0 | title1          |
|            2 |                  1 | title2          |
|            3 |                  1 | title3          |
|            4 |                  1 | title4          |
|            5 |                  2 | title5          |
|            6 |                  2 | title6          |
|            7 |                  2 | title7          |
|            8 |                  0 | title8          |
|            9 |                  2 | title9          |
|           10 |                  2 | title10         |
|           11 |                  2 | title11         |
|           12 |                  0 | title12         |
|           13 |                  0 | title13         |
|           14 |                  0 | title14         |
|           15 |                 10 | title15         |
|           16 |                  1 | title16         |
|           17 |                  0 | title17         |
|           18 |                 15 | title18         |
|           19 |                  0 | pc1             |
|           20 |                 18 | 111111          |
+--------------+--------------------+-----------------+

创建数据库连接
Java代码 复制代码  收藏代码
  1. package com.common;   
  2. import java.sql.* ;   
  3. public class DBConnection {   
  4.        
  5.     private String DB = "com.mysql.jdbc.Driver" ;   
  6.     private String URL = "jdbc:mysql://localhost/business" ;   
  7.     private String NAME = "root" ;   
  8.     private String PWD = "123456" ;   
  9.     private Connection conn = null ;   
  10.        
  11.        
  12.        
  13.     public DBConnection(){   
  14.         try{   
  15.             Class.forName(DB) ;   
  16.             conn = DriverManager.getConnection(URL,NAME,PWD) ;   
  17.         }catch(Exception e){   
  18.             System.out.println(e);   
  19.                    
  20.         }   
  21.        
  22.     }   
  23.        
  24.     public Connection getConnection(){   
  25.         return this.conn ;   
  26.     }   
  27.        
  28.     public void close(ResultSet rs , PreparedStatement pstm){   
  29.         try{   
  30.             conn.close() ;   
  31.             rs.close();   
  32.             pstm.close() ;   
  33.                
  34.         }catch(Exception e){   
  35.             System.out.println(e);   
  36.         }   
  37.            
  38.     }   
  39.   
  40. }  
package com.common;
import java.sql.* ;
public class DBConnection {
	
	private String DB = "com.mysql.jdbc.Driver" ;
	private String URL = "jdbc:mysql://localhost/business" ;
	private String NAME = "root" ;
	private String PWD = "123456" ;
	private Connection conn = null ;
	
	
	
	public DBConnection(){
		try{
			Class.forName(DB) ;
			conn = DriverManager.getConnection(URL,NAME,PWD) ;
		}catch(Exception e){
			System.out.println(e);
				
		}
	
	}
	
	public Connection getConnection(){
		return this.conn ;
	}
	
	public void close(ResultSet rs , PreparedStatement pstm){
		try{
			conn.close() ;
			rs.close();
			pstm.close() ;
			
		}catch(Exception e){
			System.out.println(e);
		}
		
	}

}



递归程序

Java代码 复制代码  收藏代码
  1. package com.test ;   
  2.   
  3.     import java.sql.PreparedStatement;   
  4. import java.sql.ResultSet;   
  5. import java.util.ArrayList;   
  6. import java.util.List;   
  7.   
  8. import com.common.DBConnection;   
  9. import com.vo.NewsClass;   
  10.   
  11.     public class Test {   
  12.            
  13.         List l = new ArrayList() ;   
  14.            DBConnection dbc = new DBConnection() ;   
  15.            PreparedStatement pstm = null ;   
  16.   
  17. /*  
  18.  这里的int parentid和String sql说明  
  19. 1、parentid就是父ID,想从哪一层开始查询就输入相应的数字,一般父ID为0的是顶级分类,下面程序以父ID为0做演示  
  20. 2、因为我有几个表都要调用到递归,所以我没有把sql写死,设置为从外面传进来,这样不同表就可以有不同的sql语句了  
  21.  */      
  22.            public ResultSet child(int parentid,String sql){   
  23.                ResultSet rs2 = null ;   
  24.                try{   
  25.                    pstm = dbc.getConnection().prepareStatement(sql) ;   
  26.                    pstm.setInt(1,parentid) ;   
  27.                     rs2 = pstm.executeQuery() ;   
  28.                }catch(Exception e){    
  29.                }                  
  30.                return rs2 ;               
  31.            }   
  32.               
  33. //递归的方法    
  34.        
  35.            public void showTree(int parentid,int level,String sql)throws Exception{ //level就是用于分出层次结构                     
  36.               ResultSet rs = child(parentid,sql) ;//查询父ID,把该层查询到的数据都存放到resultset里面,因为我们查询的父ID是0,所以第一次运行时查询出的是最顶层   
  37.                try{   
  38.                    while(rs.next()){   
  39.                       // System.out.println(rs.getString(3)) ;   
  40.                        parentid = rs.getInt(1) ;//此处是关键,把获取到的数据的ID存到parentid中,那么下面递归的时候就会查询出该记录是否有子分类了                     String str = "|___ " ;   
  41.                        for(int i=0;i<level;i++){//判断level,每加一级就多一个...,这样显示出层次感   
  42.                              str=" . . . "+str ;   
  43.                        }   
  44.   
  45.                        System.out.println(str+rs.getString(3));//输出结果   
  46.                        showTree(parentid,level+1,sql) ; //递归开始了,再次调用自身方法   
  47.                    }       
  48.                }catch(Exception e){                   
  49.                }   
  50.            }   
  51.            public static void main(String args[])throws Exception{   
  52.                String sql = "select * from news_class where newsclass_parentid=?" ;//自己定义sql,这样比较灵活,根据父ID查询出数据   
  53.                Test tree = new Test() ;   
  54.                tree.showTree(00, sql) ;//为了演示,从父ID为0,也就是顶级分类开始查询   
  55.            }       
  56.     }  
package com.test ;

	import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import com.common.DBConnection;
import com.vo.NewsClass;

	public class Test {
		
		List l = new ArrayList() ;
		   DBConnection dbc = new DBConnection() ;
		   PreparedStatement pstm = null ;

/*
 这里的int parentid和String sql说明
1、parentid就是父ID,想从哪一层开始查询就输入相应的数字,一般父ID为0的是顶级分类,下面程序以父ID为0做演示
2、因为我有几个表都要调用到递归,所以我没有把sql写死,设置为从外面传进来,这样不同表就可以有不同的sql语句了
 */	  
		   public ResultSet child(int parentid,String sql){
			   ResultSet rs2 = null ;
			   try{
				   pstm = dbc.getConnection().prepareStatement(sql) ;
				   pstm.setInt(1,parentid) ;
				    rs2 = pstm.executeQuery() ;
			   }catch(Exception e){ 
			   }			   
			   return rs2 ;			   
		   }
		   
//递归的方法 
	
		   public void showTree(int parentid,int level,String sql)throws Exception{ //level就是用于分出层次结构				   
			  ResultSet rs = child(parentid,sql) ;//查询父ID,把该层查询到的数据都存放到resultset里面,因为我们查询的父ID是0,所以第一次运行时查询出的是最顶层
			   try{
				   while(rs.next()){
					  // System.out.println(rs.getString(3)) ;
					   parentid = rs.getInt(1) ;//此处是关键,把获取到的数据的ID存到parentid中,那么下面递归的时候就会查询出该记录是否有子分类了					   String str = "|___ " ;
					   for(int i=0;i<level;i++){//判断level,每加一级就多一个...,这样显示出层次感
						     str=" . . . "+str ;
					   }

					   System.out.println(str+rs.getString(3));//输出结果
					   showTree(parentid,level+1,sql) ; //递归开始了,再次调用自身方法
				   } 	
			   }catch(Exception e){				   
			   }
		   }
		   public static void main(String args[])throws Exception{
			   String sql = "select * from news_class where newsclass_parentid=?" ;//自己定义sql,这样比较灵活,根据父ID查询出数据
			   Test tree = new Test() ;
			   tree.showTree(0, 0, sql) ;//为了演示,从父ID为0,也就是顶级分类开始查询
		   }	
	}



输出结果为
Java代码 复制代码  收藏代码
  1. |___ title1   
  2.  . . . |___ title2   
  3.  . . .  . . . |___ title5   
  4.  . . .  . . . |___ title6   
  5.  . . .  . . . |___ title7   
  6.  . . .  . . . |___ title9   
  7.  . . .  . . . |___ title10   
  8.  . . .  . . .  . . . |___ title15   
  9.  . . .  . . .  . . .  . . . |___ title18   
  10.  . . .  . . .  . . .  . . .  . . . |___ 111111  
  11.  . . .  . . . |___ title11   
  12.  . . . |___ title3   
  13.  . . . |___ title4   
  14.  . . . |___ title16   
  15. |___ title8   
  16. |___ title12   
  17. |___ title13   
  18. |___ title14   
  19. |___ title17   
  20. |___ pc1  
|___ title1
 . . . |___ title2
 . . .  . . . |___ title5
 . . .  . . . |___ title6
 . . .  . . . |___ title7
 . . .  . . . |___ title9
 . . .  . . . |___ title10
 . . .  . . .  . . . |___ title15
 . . .  . . .  . . .  . . . |___ title18
 . . .  . . .  . . .  . . .  . . . |___ 111111
 . . .  . . . |___ title11
 . . . |___ title3
 . . . |___ title4
 . . . |___ title16
|___ title8
|___ title12
|___ title13
|___ title14
|___ title17
|___ pc1




总结
1、ID和父ID之间的关系
从数据库和输出结果可以观察出,父ID为0的分类为顶级分类,之上再无父级
如title 1、8、12、13、14、17、pc1这几个都是顶级分类
而如title 2、3、4、16,他们的父ID为1,也就是title1的ID,则他们就是title1的子分类
而同时也有一些记录的父ID指定到title 2、3、4、16的ID上,所以title 2、3、4、16之中也有自己的子类
如title 2、10,上面有父级分类,下面也有子级分类

2、parentid = rs.getInt(1) ;
在showTree方法中,因为我们parentid初始值设定是0,所以第一次的结果获取到的应该是先把title1输出
然后接着parentid = rs.getInt(1),这句话就是说把title1的ID放到parentid里,title1的ID为1,所以这时候的parentid的值改变为1,这样下面的
showTree(parentid,level+1,sql) ;就会从parentid为1开始查询,查询title1的子分类,再把子分类的ID放到parentid里,又查询子分类的子子分类,以次类推下去,直到把所有的子类都查询出来为止。

个人认为递归是关键,理解好递归了才好做出来

你可能感兴趣的:(数据结构,sql,mysql,jdbc)