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



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

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

 

提供了两个查询方法:

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

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

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