Mysql中使用树的设计
16lz
2021-01-22
原来一直使用id与 parent_id结合的办法设计树,最近发现有些问题:
1、查询此结点下所有子结点的需求。
2、查询此结点上所有父结点的需求。
这些需求在oracle和sql server中可以使用一些办法在数据库端进行处理,但在mysql中处理就稍显麻烦,在sqlite中基本无解。所以想办法重新设计一下就显的很有必要的了。
添加两列:structure_node varchar(128)和 level int(11)
root 001
第一级第一个结点 001 001
第一级第二个结点 001 002
第二级第一个结点 001 001 001
这样查询起来就很方便了。
问题来了,
问题1:将现在id与parent_id的结构迁移到新结构上:
import java.io.FileInputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import com.jfinal.plugin.activerecord.ActiveRecordPlugin; import com.jfinal.plugin.activerecord.Db; import com.jfinal.plugin.activerecord.Record; import com.jfinal.plugin.druid.DruidPlugin; public class Main { public static List<String> list_parent_id=new ArrayList<String>(); public static List<String> list_sql=new ArrayList<String>(); /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { Properties prop = new Properties(); String classDir = Main.class.getResource("/").getPath(); FileInputStream fis = new FileInputStream(classDir+"/dsideal_config.properties"); prop.load(fis); // 配置druid数据库连接池插件 String driver =prop.getProperty("driverClass"); DruidPlugin druidPlugin = new DruidPlugin(prop.getProperty("jdbcUrl"), prop.getProperty("user"), prop.getProperty("password"), driver); druidPlugin.start(); // 配置ActiveRecord插件 ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin); arp.start(); String sql="select distinct scheme_id from t_resource_structure"; List<Record> scheme_list= Db.find(sql); for(int t=0;t<scheme_list.size();t++) { list_parent_id.clear(); String scheme_id=scheme_list.get(t).get("scheme_id").toString(); //设置根 sql="update t_resource_structure set structure_node='001',level=1 where structure_id=?"; Db.update(sql,scheme_id); list_parent_id.add(scheme_id); int level=1; while(list_parent_id.size()>0) { level++; update_node_byparent_id(level); } } System.out.println("结构转换成功完成!"); //提取新的映射关系到map里 Map<String,String> mymap=new HashMap<String,String>(); sql="select structure_id,structure_node from t_resource_structure"; List<Record> myr= Db.find(sql); for(int i=0;i<myr.size();i++) { mymap.put(myr.get(i).get("structure_id").toString(), myr.get(i).get("structure_node").toString()); } //获取到资源表中的对应数据 sql="select resource_id,node_id from t_resource_base"; myr= Db.find(sql); for(int i=0;i<myr.size();i++) { list_sql.add("update t_resource_base set structure_node='"+mymap.get(myr.get(i).get("node_id"))+"' where resource_id='"+myr.get(i).get("resource_id")+"'"); } System.out.println("正在提交资源的数据,请稍等..."); //事务提交 Db.batch(list_sql, 1000); System.out.println("所有操作成功完成!"); } private static void update_node_byparent_id(int level) { List<String> tmp_list_parent_id=new ArrayList<String>(); for( int k=0;k<list_parent_id.size();k++) { System.out.println("正在处理,共"+list_parent_id.size()+"个,第"+(k+1)+"个"); String sql="SELECT structure_id,parent_id FROM t_resource_structure where parent_id=? order by sort_id"; List<Record> mylist= Db.find(sql,list_parent_id.get(k)); for(int i=0;i<mylist.size();i++) { tmp_list_parent_id.add(mylist.get(i).get("structure_id").toString()); int code=1000+(i+1); //父结点的node sql="select structure_node from t_resource_structure where structure_id=?"; String parent_structure_node=Db.queryStr(sql,mylist.get(i).get("parent_id").toString()); String result_code=parent_structure_node+String.valueOf(code).substring(1,4); sql="update t_resource_structure set structure_node='"+result_code+"',level="+level+" where structure_id='"+mylist.get(i).get("structure_id")+"'"; Db.update(sql); } } list_parent_id.clear(); list_parent_id=tmp_list_parent_id; } }