数据库设计
现在要设计一个目录数据库表,即一个表中存有根目录和各级子目录,这时候我们可以设计一张表,用parent_id来存储子目录对应的父目录的序号,设计表如下:
表的字段类型:
+-----------+----------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+----------------------+------+-----+---------+----------------+ | type_id | smallint(5) unsigned | NO | PRI | NULL | auto_increment | | type_name | varchar(20) | NO | | NULL | | | parent_id | smallint(5) unsigned | YES | | 0 | | +-----------+----------------------+------+-----+---------+----------------+
表的内容:
+---------+-----------------------+-----------+ | type_id | type_name | parent_id | +---------+-----------------------+-----------+ | 1 | 图书 | 0 | | 2 | 科技 | 1 | | 3 | 摄影技术 | 2 | | 4 | 电子与通信 | 2 | | 5 | 建筑 | 2 | | 6 | 真空电子技术 | 4 | | 7 | 无线通信 | 4 | | 8 | 半导体技术 | 4 | | 9 | 摄影理论 | 3 | | 10 | 摄影机具与设备 | 3 | | 11 | 建筑史 | 5 | | 12 | 建筑设计 | 5 | | 13 | 建筑材料 | 5 | | 14 | 经济 | 1 | | 15 | 历史 | 1 | | 16 | 现代经济 | 14 | | 17 | 古代经济 | 14 | | 18 | 中国历史 | 15 | | 19 | 西方历史 | 15 | +---------+-----------------------+-----------+
从表中,我们可以得知,图书为根目录,科技是图书的一级子目录,然后摄影技术又是科技的子目录...等等,现在我们想通过Java的JDBC来得到这样的目录层次关系。
Java程序设计
package demo0807; /** * 获取数据库的目录表 */ import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; public class DB { //数据库名称 private String dbName; //数据库登录名 private String userName; //数据库登录密码 private String password; //Statement对象 private static Statement statement=null; //用于存储结果的散列表 private LinkedList<Map<String, ArrayList<String>>> linkedList=new LinkedList<Map<String,ArrayList<String>>>(); //含参构造函数 public DB(String dbName, String userName, String password) { this.dbName = dbName; this.userName = userName; this.password = password; } /** * 获取数据表的根目录 * @return 根目录线性表 */ public ArrayList<String> getRootOrder() { String sql=null; ResultSet resultSet=null; Connection connection=null; ResultSetMetaData metaData=null; int columnCount = 0; ArrayList<String> parentList = new ArrayList<String>(); try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { System.err.println("无法启动mysql.jdbc驱动!"); } try { connection = DriverManager.getConnection( "jdbc:mysql://localhost/"+dbName ,userName,password); } catch (SQLException e) { System.err.println("驱动管理器无法连接到数据库!"); } //sql语句 sql=" select type_name as 根目录 from tb3 where parent_id=0;"; //执行sql语句 try { statement=connection.createStatement(); resultSet=statement.executeQuery(sql); } catch (SQLException e) { System.err.println("无法执行查询"); } try { //获取结果的信息元数据 metaData = resultSet.getMetaData(); //获取列的总数 columnCount = metaData.getColumnCount(); } catch (SQLException e) { System.out.println("无法获取表信息"); } try { while(resultSet.next()) { int index=1; while(index<=columnCount) { parentList.add(resultSet.getString(index)); index++; } } } catch (SQLException e) { System.err.println("无法正确查询结果"); } return parentList; } /** * 递归地找出所有的目录结构 * 找法一:找出所有目录的子目录,直到子目录为空为止 * @param parentOrder * @return */ public LinkedList<Map<String, ArrayList<String>>> lookupSubOrder(ArrayList<String> parentOrder) { ResultSet resultSet=null; for(String dynamicParent:parentOrder) { //Map类型,用于存储key-value Map<String,ArrayList<String>> map=new HashMap<String,ArrayList<String>>(); String key=dynamicParent; ArrayList<String> value = new ArrayList<String>(); String sql="select child_type_name from (select p.type_id as type_id,p.type_name as type_name,s.type_name as child_type_name from tb3 as p left join tb3 as s on p.type_id=s.parent_id) as tb_tmp where type_name="+"‘"+dynamicParent+"‘"; try { resultSet = statement.executeQuery(sql); if(resultSet.next()==false) { ; } else { boolean flag=true; while(flag) { String tmp=null; if((tmp=resultSet.getString(1))!=null) { value.add(tmp); } flag=resultSet.next(); } lookupSubOrder(value); } map.put(key, value); } catch (SQLException e) { System.err.println("数据库查询失败!"); e.printStackTrace(); } linkedList.add(map); } return linkedList; } }
测试代码
package demo0807; /** * 测试类 */ import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.Map; import java.util.Map.Entry; import java.util.Set; public class Test { public static void main(String[] args) { DB db = new DB("demo2", "root", "031422zw"); ArrayList<String> mainOrder = db.getRootOrder(); System.out.println("根目录为:"+mainOrder.toString()); LinkedList<Map<String, ArrayList<String>>> linkedListSubOrder = db.lookupSubOrder(mainOrder); while(!linkedListSubOrder.isEmpty()) { Map<String, ArrayList<String>> subOrder = linkedListSubOrder.removeLast(); Set<Entry<String, ArrayList<String>>> entrySet = subOrder.entrySet(); Iterator<Entry<String, ArrayList<String>>> iterator = entrySet.iterator(); while(iterator.hasNext()) { Entry<String, ArrayList<String>> next = iterator.next(); String parent=next.getKey(); ArrayList<String> children = next.getValue(); if(!children.isEmpty()) { System.out.println(parent+"的子目录有"+children.toString()); } } } } }
运行结果
根目录为:[图书] 图书的子目录有[科技, 经济, 历史] 历史的子目录有[中国历史, 西方历史] 经济的子目录有[现代经济, 古代经济] 科技的子目录有[摄影技术, 电子与通信, 建筑] 建筑的子目录有[建筑史, 建筑设计, 建筑材料] 电子与通信的子目录有[真空电子技术, 无线通信, 半导体技术] 摄影技术的子目录有[摄影理论, 摄影机具与设备]
总结
程序还有很多小瑕疵,感觉熟悉基本的数据结构和递归算法对编程的帮助很大!
时间: 2024-09-29 08:24:27