標籤:
資料庫設計
現在要設計一個目錄資料庫表,即一個表中存有根目錄和各級子目錄,這時候我們可以設計一張表,用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-valueMap<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());}}}}}
運行結果
根目錄為:[圖書]圖書的子目錄有[科技, 經濟, 曆史]曆史的子目錄有[中國歷史, 西方曆史]經濟的子目錄有[現代經濟, 古代經濟]科技的子目錄有[攝影技術, 電子與通訊, 建築]建築的子目錄有[建築史, 建築設計, 建築材料]電子與通訊的子目錄有[真空電子技術, 無線通訊, 半導體技術]攝影技術的子目錄有[攝影理論, 攝影機具與裝置]
總結
程式還有很多小瑕疵,感覺熟悉基本的資料結構和遞迴演算法對編程的協助很大!
運用Java遞迴擷取資料庫的目錄表結構