In web development, the operation of tree data is often encountered, such as menu, organization, administrative district (province, city, county) and other data with hierarchical relationship. The following example illustrates the storage and implementation of tree-shaped data (hierarchical relational data).
1 database table structure design
Tree data generally through the parent node and child nodes to achieve hierarchical association between data, hierarchical relationship in the database mainly through the primary key and foreign key to achieve.
--Using the Oracle database--Create the Administrative table created table TB_XZQ (code number NOT NULL,--Administrative Code, primary key Parent_code number,--Parent row District code, if there is no upper administrative region, is empty name VARCHAR2 (50)--the name of the canton);--set code to primary key ALTER TABLE TB_XZQ add constraint pk_tb_xzq Prima Ry Key (CODE) using index;--setting foreign key ALTER TABLE TB_XZQ ADD constraint Fk_tb_xzq_parent_code foreign key (Parent_code) refere NCEs Tb_xzq (CODE) on delete set null;--inserting the administrative data insert into TB_XZQ (code,parent_code,name) VALUES (420000, NULL, ' Hubei Province '); INS ERT into TB_XZQ (code,parent_code,name) VALUES (420100, 420000, ' Wuhan '); INSERT into Tb_xzq (code,parent_code,name) VALUES ( 420101, 420100, ' districts '); insert into Tb_xzq (code,parent_code,name) VALUES (420102, 420100, ' Jiang ' an '); insert into Tb_xzq (CODE, Parent_code,name) VALUES (420103, 420100, ' Jianghan District '), INSERT into Tb_xzq (code,parent_code,name) VALUES (420104, 420100, ' Qiaokou District ' Insert into TB_XZQ (code,parent_code,name) VALUES (420105, 420100, ' Hanyang District ') and insert into TB_XZQ (code,parent_code,name) VA Lues (421000, 420000, ' Jingzhou cityInsert into TB_XZQ (code,parent_code,name) VALUES (421001, 421000, ' Municipal District '), insert into TB_XZQ (code,parent_code,name) V Alues (421002, 421000, ' Shashi District '); insert into Tb_xzq (code,parent_code,name) VALUES (421003, 421000, ' Jinzhou District '); INSERT INTO TB_XZQ (Code,parent_code,name) VALUES (430000, NULL, ' Hunan Province '), insert into TB_XZQ (code,parent_code,name) VALUES (430100, 430000, ' Changsha '); INSERT INTO TB_XZQ (Code,parent_code,name) VALUES (430101, 430100, ' districts '); insert into TB_XZQ (code,parent_code,name) VALUES (430102, 430100, ' Furong '); INSERT INTO TB_XZ Q (Code,parent_code,name) VALUES (430103, 430100, ' Tianxin District '); INSERT into Tb_xzq (code,parent_code,name) VALUES (430104, 43010 0, ' Yuelu District ');
After inserting the data as shown
2 Tree-shaped data Java implementation
Typically, the data that is read from the database needs to be converted to a tree structure. TreeNode is a Java tree data implementation class, through the static method Buildtree can easily build TreeNode into a tree.
Import java.util.arraylist;import java.util.list;/** * tree node, support for Ext, Ztree and other Web controls * * @author [email protected] * @param <T> tree node binding data class */public class Treenode<t> {/** * tree Node ID * For compatibility with multiple cases, string id;/** * tree node ancestor ID */private string parentid;/** * tree node displays text */private string text;/** * tree node name, content as text * This field is primarily compatible with ext and ztree */private Strin G name;/** * is the leaf node */private boolean leaf = true;private Boolean expanded = False;private T nodedata;/** * is the parent node, the field and Le AF repeats primarily for compatibility with ext and ztree */private Boolean isparent = false;/** * child nodes, if there are no child nodes, the list length is 0 */private list<treenode<t>& Gt Children = new Arraylist<treenode<t>> ();p ublic String getId () {return ID;} public void SetId (String id) {this.id = ID;} Public String Getparentid () {return parentid;} public void Setparentid (String parentid) {this.parentid = ParentID;} Public String GetText () {return text;} public void SetText (String text) {this.name = Text;this.text = text;} Public String GetName () {return name;} Public void SetName (String name) {this.name = Name;this.text = name;} Public Boolean getexpanded () {return expanded;} public void setexpanded (Boolean expanded) {this.expanded = expanded;} Public list<treenode<t>> GetChildren () {return children;} public void Setleaf (Boolean leaf) {this.leaf = Leaf;this.isparent =!leaf;} Public Boolean Getleaf () {return this.leaf;} Public Boolean getisparent () {return isparent;} public void Setisparent (Boolean isparent) {this.isparent = Isparent;this.leaf =!isparent;} Public T Getnodedata () {return nodedata;} public void Setnodedata (T nodedata) {this.nodedata = Nodedata;} /** * Constructs a tree node list into a tree, and finally returns the root node of the tree, and dynamically creates a root node if the incoming list has multiple root nodes. * @param nodes tree Node list * @return root node */public static <T> treenode<t> buildtree (list<treenode<t>> nod ES) {if (nodes = = NULL | | nodes.size () = = 0) {return null;} if (nodes.size () = = 1) {return nodes.get (0);} Used to store nodes inside the top tree node//That is, the node without the parent node is put into the tops inside to list<treenode<t>> tops = new ARRAYLIST<TREENODE<T>> (); Boolean hasparent = false;//First traversal, gets a node as a child node for (treenode<t> child:nodes) {hasparent = false;// The parent node of the current node child idstring pid = Child.getparentid ();//If the PID does not exist or is empty//The current node is the top node if (PID = = NULL | | pid.equals ("")) {// Add the current node to tops as the top node tops.add (child);//Skip the current node and go to the next round of continue;} Traverse all nodes on the nodes to determine if there is a child's parent node for (treenode<t> parent:nodes) {String id = parent.getid ();/ If the ID of the parent node equals the child node's PID, then the parent node is the child node's parents node if (id! = NULL && id.equals (PID)) {// Add child to Parent under Parent.getchildren (). Add (Child);p arent.setleaf (false);//child node has parent node hasparent = true;continue;}} If the child node does not have a parent node, child is the top-level node//Add child to tops if (!hasparent) {tops.add (child);}} Treenode<t> root;if (tops.size () = = 1) {//If the top-level node has only one, the top-level node is the root node, root = Tops.get (0);} else{//If there are multiple top-level nodes, create a root node, place the top-level node under root = new treenode<t> (), Root.setleaf (false), Root.setid ("1"); Root.setname ("root"); Root.setparentid (""); Root.getchildren (). AddAll (tops);} return root;}}
3 Generating the administrative tree
Dao (only major code listed)
@Repository ("Xzqdao") public class Xzqdaoimpl implements Xzqdao {@Resourceprivate JdbcTemplate jdbctemplate;public List <XzqEntity> Select () {String sql = "Select Code,parent_code,name from Tb_xzq";//Database operation with spring JDBC return Jdbctemplate.query (SQL, new rowmapper<xzqentity> () {public xzqentity Maprow (ResultSet rs, int index) throws SQLException {xzqentity xzq = new xzqentity (); Xzq.setcode (Rs.getint ("CODE")); Xzq.setname (rs.getstring ("NAME")); Xzq.setparentcode (Rs.getint ("Parent_code")); return xzq;});}}
Service (column-only primary code)
@Service ("Xzqservice") public class Xzqserviceimpl implements Xzqservice {@Resourceprivate Xzqdao xzqdao;public Treenode<xzqentity> tree () {list<xzqentity> List = Xzqdao.select (); list<treenode<xzqentity>> nodes = new arraylist<treenode<xzqentity>> ();//Convert the administrative class to tree node for ( xzqentity xzq:list) {treenode<xzqentity> node = new treenode<xzqentity> ();//Node Idnode.setid (Xzq.getCode () . ToString ());//Node ancestor Idnode.setparentid (Xzq.getparentcode (). ToString ()); Node.settext (Xzq.getname ());// Place the Canton class in the node data for use with Node.setnodedata (XZQ); Nodes.Add (node);} return Treenode.buildtree (nodes);}}
Controller (main code listed only)
@Controller @requestmapping ("/xzq") public class Xzqcontroller {@Resourceprivate xzqservice xzqservice;/** * Administrative tree, Returns the JSON format * * @param response */@RequestMapping ("/TREE.MVC") public void Tree (HttpServletResponse response) {String JSON = ""; try {json = json.tojsonstring (Xzqservice.tree ());} catch (Exception e) {e.printstacktrace ();} Output JSON data//here directly through the response output JSON string//spring MVC also provides a way to output JSON data//Set the encoding format Response.setcontenttype ("Text/plain; Charset=utf-8 "); Response.setcharacterencoding (" Utf-8 "); PrintWriter out = null;try {out = Response.getwriter (); Out.write (JSON); Out.flush ();} catch (IOException e) { E.printstacktrace ();}}}
Ztree display of the borough tree
<%@ page language= "java" contenttype= "text/html; Charset=utf-8 "pageencoding=" UTF-8 "%><%string context = Request.getcontextpath ();%><! DOCTYPE HTML PUBLIC "-//w3c//dtd HTML 4.01 transitional//en" "Http://www.w3.org/TR/html4/loose.dtd" >
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
The implementation of tree data (hierarchical relational data) in the Web--a case study of the administrative district tree