数据库中树结构数据,转换为Java对象树结构( 多叉树结构 )

来源:互联网 发布:大数据顾客需求 编辑:程序博客网 时间:2024/06/08 13:33

总体就是图所表示所表示的转换,由数据库 =>Java对象转换,代码比较简单


提供了两个查询方法:

No.1 : Map<String,List<Tree>> arrMap = queryGroupToMap();//No.1(不推荐使用,运行时间较长)

No.1.1:Map<StringList<Tree>>arrMap=queryListToMap();//No.1.1(推荐使用,运行时间较短)

这个两方法返回的Map内格式是一样的.都是Map<StringList<Tree>> ,  key就是这组List<Tree>的父ID, value就是这组List


主要是对象之间建立关联 No.2 : MapForTree(arrMap);


思路为: 用pid(父id)作分组 ,这样每一个组的父节点是同一样,换句话说就是同一分组里,所有节点pid是相同的.这样就针对分组操作,建立两重关联,子节点持有父节点对象,父节点持有子节点List. 就是说通过一个节点可以找得到自己的父节点与子节点


用Map做封装,key为父ID, value为分组List

用到了QueryRunner这个是数据库工具,只要在网上找,下载就可以,能直接查询List. 

QueryRunner jar包名=> commons-dbutils-1.5.jar 


 DTO代码:tree 类的代码.Javabean:

[java] view plain copy
在CODE上查看代码片派生到我的代码片
  1. private String AREA_ID; // 主键ID  
  2.     private String AREA_NAME;   // 用来显示的名称  
  3.     private String PARENT_ID;   // 父ID  参照AREA_ID  
  4.     private Tree parentObj; // 父节点对象  
  5.     private List<Tree> childrenList = new ArrayList<Tree>();    // 子节点  



执行代码:

[java] view plain copy
在CODE上查看代码片派生到我的代码片
  1. import java.sql.Connection;  
  2. import java.sql.DriverManager;  
  3. import java.sql.SQLException;  
  4. import java.util.ArrayList;  
  5. import java.util.HashMap;  
  6. import java.util.Iterator;  
  7. import java.util.List;  
  8. import java.util.Map;  
  9. import java.util.Properties;  
  10. import java.util.Set;  
  11.   
  12. import org.apache.commons.dbutils.DbUtils;  
  13. import org.apache.commons.dbutils.QueryRunner;  
  14. import org.apache.commons.dbutils.handlers.BeanListHandler;  
  15. import org.apache.commons.dbutils.handlers.ColumnListHandler;  
  16.   
  17. /** 
  18.  * 数据库中树结构数据,转换为Java对象树结构( 多叉树结构 ) 
  19.  * @author liupengyuan 
  20.  * 
  21.  */  
  22. public class ListToTree {  
  23.       
  24.     /** 
  25.      * No.0: 
  26.      * @param args 
  27.      * @throws Exception 
  28.      */  
  29.     public static void main(String[] args) throws Exception {  
  30.         long startTime=System.currentTimeMillis();   //获取开始时间  
  31.           
  32.           
  33.         // 从数据库中查询所以分组的节点  
  34. //      Map<String, List<Tree>> arrMap = queryGroupToMap(); //No.1  (不推荐使用 运行时间较长)  
  35.         Map<String, List<Tree>> arrMap = queryListToMap();  //No.1.1  (推荐使用 运行时间较短)  
  36.   
  37.         //  No.2:让节点与子节点之间彼此关联,并返回全有的根.(没有父节点的都为根)  
  38.         List<Tree> rootTreeList = MapForTree(arrMap);  
  39.   
  40.         //  从map里把根找到.返回List . 可能有多个根  
  41.         List<Tree> list = arrMap.get("root");  
  42.         System.out.println(list.size());  
  43.           
  44.           
  45.         //获取结束时间  
  46.         long endTime=System.currentTimeMillis();  
  47.         System.out.println("程序运行时间: "+(endTime-startTime)+"ms");  
  48.     }  
  49.       
  50.       
  51.     /**  
  52.      * No.1:  
  53.      * 通过多条sql查询完成,数据库压力大( 不推荐使用 ). 
  54.      * 用父ID分组,用Map封装. key为父ID, value是所有父ID为KEY的节点数组. 
  55.      * 每个数组里都是一组子节点,他们的根是同一个. 换句话说它们的父ID相同, 而Map的Key就是他们是父ID. 
  56.      * @return 
  57.      * @throws SQLException 
  58.      */  
  59.     @SuppressWarnings({ "deprecation""unchecked""rawtypes" })  
  60.     public static Map<String,List<Tree>> queryGroupToMap() throws SQLException{  
  61.           
  62.         /* 
  63.          * 该表为中国地区组织,到 区县级 
  64.          * 比如,中国下分:北京市,河北省,山东省... 
  65.          * 山东下分:济南市,青岛市,烟台市... 
  66.          *  
  67.          */  
  68.           
  69.         // QueryRunner 这个是数据库工具,只要在网上找下载就可以 commons-dbutils-1.5.jar  
  70.         QueryRunner qr = new QueryRunner();  
  71.         Connection connection = getJdbcConnection("jdbc:oracle:thin:@192.168.3.34:1521:ORCL""DSD_ZJK""DSD_ZJK""oracle.jdbc.driver.OracleDriver");  
  72.         /* 
  73.          * 用父Id分组查询,找到所有的父ID 
  74.          * 然后循环这个List查询 
  75.          */  
  76.         String sqlGroup = "select parent_id from  HM_F_AREA t group by t.parent_id";  
  77.         List<String> sqlGroupList = (List<String>)qr.query(connection, sqlGroup, new String[]{}, new ColumnListHandler("PARENT_ID"));  
  78.   
  79.         Map<String,List<Tree>> arrMap = new HashMap<String,List<Tree>>(sqlGroupList.size());  
  80.         for(int i=0; i <sqlGroupList.size(); i++){  
  81.             String _pid = sqlGroupList.get(i);  
  82.             String sql = "select area_id , area_name , parent_id from  HM_F_AREA t where t.parent_id = '"+_pid + "'";  
  83.             List<Tree> listTree = (List<Tree>) qr.query(connection, sql, new String[]{} , new BeanListHandler(Tree.class));  
  84.             arrMap.put( _pid , listTree );  
  85.         }  
  86.         DbUtils.close(connection);  
  87.         return arrMap;  
  88.     }  
  89.       
  90.       
  91.     /**  
  92.      * No.1.1:  
  93.      * 通过两条sql查询完成.数据库压力较小些(推荐使用这个方法,运行的时间比 queryGroupToMap 短一半). 
  94.      * 用父ID分组,用Map封装. key为父ID, value是所有父ID为KEY的节点数组. 
  95.      * 每个数组里都是一组子节点,他们的根是同一个. 换句话说它们的父ID相同, 而Map的Key就是他们是父ID. 
  96.      * @return 
  97.      * @throws SQLException 
  98.      */  
  99.     @SuppressWarnings({ "unchecked""deprecation""rawtypes"})  
  100.     public static Map<String,List<Tree>> queryListToMap() throws SQLException{  
  101.           
  102.         /* 
  103.          * 该表为中国地区组织,到 区县级 
  104.          * 比如,中国下分:北京市,河北省,山东省... 
  105.          * 山东下分:济南市,青岛市,烟台市... 
  106.          *  
  107.          */  
  108.           
  109.         // QueryRunner 这个是数据库工具,只要在网上找下载就可以 commons-dbutils-1.5.jar  
  110.         QueryRunner qr = new QueryRunner();  
  111.         Connection connection = getJdbcConnection("jdbc:oracle:thin:@192.168.3.34:1521:ORCL""DSD_ZJK""DSD_ZJK""oracle.jdbc.driver.OracleDriver");  
  112.           
  113.         //用父Id分组查询,找到所有的父ID然后循环这个List查询  
  114.         String sqlGroup = "select parent_id from  HM_F_AREA t group by t.parent_id";  
  115.         List<String> sqlGroupList = (List<String>)qr.query(connection, sqlGroup, new String[]{}, new ColumnListHandler("PARENT_ID"));  
  116.   
  117.         //查询出所有的节点  
  118.         Map<String,List<Tree>> arrMap = new HashMap<String,List<Tree>>(sqlGroupList.size());  
  119.         String sql = "select area_id , area_name , parent_id from  HM_F_AREA t ";  
  120.         List<Tree> listTree = (List<Tree>) qr.query(connection, sql, new String[]{} , new BeanListHandler(Tree.class));  
  121.         DbUtils.close(connection);  
  122.           
  123.           
  124.         /* 
  125.          * 通过 父ID 和 所有的节点 比对 
  126.          */  
  127.         for(int k=0;k<sqlGroupList.size();k++){  
  128.             String pid = sqlGroupList.get(k);  
  129.               
  130.             List<Tree> tempTreeList = new ArrayList<Tree>();  
  131.             for(int i=0; i < listTree.size();i++){  
  132.                 Tree tree = listTree.get(i);  
  133.                   
  134.                 /* 
  135.                  * 将同一父ID的tree添加到同一个List中,最后将List放入Map..   arrMap.put(pid, tempTreeList); 
  136.                  * 这点虽然不复杂,但这是整个思索的中心, 
  137.                  */  
  138.                 if(pid.equals(tree.getPARENT_ID())){  
  139.                     tempTreeList.add(tree);  
  140.                 }  
  141.             }  
  142.               
  143.             // 最后将List放入Map..  key就是这组List<Tree>父ID, value就是这组List  
  144.             arrMap.put(pid, tempTreeList);  
  145.         }  
  146.           
  147.         return arrMap;  
  148.     }  
  149.       
  150.       
  151.     /** 
  152.      * No.2: 
  153.      * 让节点与子节点之间彼此关联,并返回树的根 
  154.      * 数据库格式并没有换,只是建立了关联 
  155.      * @param arrMap 
  156.      */  
  157.     public static List<Tree> MapForTree(Map<String, List<Tree>> arrMap){  
  158.           
  159.         //所以pid的集成  
  160.         Set<String> pidSet = arrMap.keySet();  
  161.           
  162.         //遍历所有的父ID,然后与所以的节点比对,父id与id相同的    //找出对应的tree节点,然后将该节点的  
  163.         for (Iterator<String> it = pidSet.iterator(); it.hasNext();) {  
  164.               
  165.             String pid = (String) it.next();  
  166.               
  167.             /* 
  168.              * 按分组的方式与pid比对. 
  169.              * 如果找到,那么将该pid分组的List,做为子节点 赋值给该找到的节点的 setChildrenList(list),同时也将找到节点赋值List内所有子节点的parentObj 
  170.              *  
  171.              */  
  172.             for (Iterator<String> it2 = pidSet.iterator(); it2.hasNext();) {  
  173.                   
  174.                 String key = (String) it2.next();  
  175.                 //不查找自己的分组  
  176.                 if(pid.equals(key)){  
  177.                 //  break;  
  178.                 }  
  179.                   
  180.                 List<Tree> list = arrMap.get(key);  
  181.                   
  182.                 //  No.3:找出对应的tree父节点对象  
  183.                 Tree parentTree = indexOfList(list , pid);  
  184.                   
  185.                   
  186.                 if(parentTree!=null){  
  187.                     //通过pid在Map里找出节点的子节点.  
  188.                     if("430000".equals(pid)){  
  189.                         System.out.println(pid);  
  190.                     }  
  191.                     List<Tree> childrenHereList = arrMap.get(pid);  
  192.                       
  193.                     //TODO  这里是我自己定义的变成成,都不一样.所以需要自定义  
  194.                     // 把子节点List赋值给Tree节点的Children  
  195.                     parentTree.setChildrenList(childrenHereList);  
  196.                       
  197.                     //TODO  这里是我自己定义的变是,都不一样.所以需要自定义  
  198.                     // 与上面相反,这是 把父节点对象赋值给Tree节点的parentObj  
  199.                     for(int i=0; i<childrenHereList.size(); i++){  
  200.                         Tree childrenHereTree = childrenHereList.get(i);  
  201.                         childrenHereTree.setParentObj(parentTree);  
  202.                     }  
  203.                 }  
  204.             }  
  205.         }  
  206.           
  207.           
  208.           
  209.         // 找到 childrenHereTree.getParentObj(); 为null的就是根  return rootTreeList  
  210.         List<Tree> rootTreeList = new ArrayList<Tree>();  
  211.         for (Iterator<String> it2 = pidSet.iterator(); it2.hasNext();) {  
  212.             String key = (String) it2.next();  
  213.             List<Tree> list = arrMap.get(key);  
  214.             for(int i=0; i<list.size(); i++){  
  215.                 Tree tree = list.get(i);  
  216.                 if(null == tree.getParentObj()){  
  217.                     rootTreeList.add(tree);  
  218.                 }  
  219.             }  
  220.         }  
  221.         return rootTreeList;  
  222.           
  223.     }  
  224.       
  225.       
  226.       
  227.     /** 
  228.      * No.3: 
  229.      * 找出 list 中元素的id与pid相同的节点 的并返回.对应关系为: id与父id相同 
  230.      * @param list 
  231.      * @param pid 
  232.      * @return 
  233.      */  
  234.     public static Tree  indexOfList(List<Tree> list , String pid){  
  235.         for(int i=0 ;i<list.size();i++){  
  236.             Tree tree = list.get(i);  
  237.             /* 
  238.              * pid:是 父ID 
  239.              * area_id:是 ID 
  240.              */  
  241.             //TODO  这里是我自己定义的变成成,都不一样.所以需要自定义  
  242.             if(pid.equals(tree.getAREA_ID())){  
  243.                 return tree;  
  244.             }  
  245.         }  
  246.         return null;  
  247.     }  
  248.       
  249.     /** 
  250.      * 数据库连接 
  251.      * @param url 
  252.      * @param username 
  253.      * @param password 
  254.      * @param driverClassName 
  255.      * @return 
  256.      */  
  257.     public static Connection getJdbcConnection(String url, String username, String password, String driverClassName){  
  258.         Connection connection = null;  
  259.         try {  
  260.               
  261.             Properties props =new Properties();  
  262.                
  263.             props.put("user",username);  
  264.             props.put("password",password);  
  265.             props.put("remarksReporting","true");  
  266.   
  267.             try {  
  268.                 Class.forName(driverClassName).newInstance();  
  269.             } catch (InstantiationException e) {  
  270.                 e.printStackTrace();  
  271.             } catch (IllegalAccessException e) {  
  272.                 e.printStackTrace();  
  273.             } catch (ClassNotFoundException e) {  
  274.                 e.printStackTrace();  
  275.             }  
  276.             connection=DriverManager.getConnection(url,props);  
  277.         } catch (SQLException e) {  
  278.             e.printStackTrace();  
  279.         }  
  280.           
  281.         return connection;  
  282.           
  283.     }  
  284.       
  285. }  
0 0
原创粉丝点击