浏览 2128 次
|
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
|---|---|
| 作者 | 正文 |
|
最后更新时间:2008-01-23
前两天分别写的前台的JS代码,以及实体结构代码,这些,是开始做树形结构要准备的基础数据
做一个好的树形结构,要做的很容易很方便的扩展,需要实现由一个服务类,来实现系统内大部需要用到的树形结构,如果每写一棵树,都要去新建一个数据库表,新写一个服务类,那太麻烦,只要我们把数据结构转化为一致的结构,用一个服务类,来生成系统中所有的树形结构,是一件很容易的事情,不管我们使用的树形结构数据是从数据库得来,还是手工写的,还是通过webservice得来的,总之,只要把数据结构转换一致,那一个项目中所使用到的树形结构,只需要一个服务类,别的,什么也不需要做. 做一小推广,希望大伙可以接受~~域名(www.faceye.com/cn/net)准备出售.我个人对域名有绝对的拥有权,在中国万网注册,由于没有时间去开发,有兴趣的朋友可以和我联系,也可以合作开发.联系方式:MSN:myecsun@hotmail.com,QQ:82676683, Mail:ecsun@sohu.com 1.服务接口: package com.faceye.core.service.security.service.iface;
import java.util.List;
import java.util.Map;
import com.faceye.core.service.iface.IBaseHibernateService;
import com.faceye.core.service.security.dao.iface.ITreeDao;
import com.faceye.core.service.security.model.Tree;
/**
*
* @author:宋海鹏
* @Connection:E_mail:ecsun@sohu.com/myecsun@hotmail.com QQ:82676683
* @Copy Right:www.faceye.com
* @System:www.faceye.com网络支持系统
* @Create Time:2007-9-22
* @Package com.faceye.core.service.security.service.iface.ITreeService.java
* @Description:树形菜单控制
*/
public interface ITreeService extends IBaseHibernateService{
/**
* 生成json树结构。
* 默认生成第一级节点的json结构
* @return
*/
public String treeJSON();
/**
* 根据父节点,当点击时生成下一级节点的json结构
* @param source
* @param treeid
* @return
*/
public String treeJSON(List source,String treeid);
/**
* 根据一个指定的结果集,生成第一级节点json结构
* 当前source中包含的元素结构为Map结构
* @param source
* @return
*/
public String treeJSON(List source);
/**
* 是否有父节点
* @param source
* @param treeid
* @return
*/
public boolean isHaveParent(List source,String treeid);
public boolean isHaveParent(List source,Map transedTree);
public boolean isHaveParent(List source,Tree tree);
/**
* 是否有子节点
* 当前List中包含的元素结构为Tree结构
* @param source
* @param tree
* @return
*/
public boolean isHaveChildren(List source,Tree tree);
/**
* 是否有子节点
* 当前source中包含的元素结构为Map结构
* @param source
* @param treeid
* @return
*/
public boolean isHaveChildren(List source,String treeid);
/**
* 取得一个集合中的所有根节点
* 当前source中包含的元素结构为Map结构
* @param source
* @return
*/
public List getRoots(List source);
/**
* 取得一个指定节点的直接子节点
* 当前source中包含的元素结构为Map结构
* @param source
* @param treeid
* @return
*/
public List getDirectChildrenTrees(List source,String treeid);
/**
* 取得一个节点的所有子节点,包括直接子节点和间接子节点
* 当前source中包含的元素结构为Map结构
* @param source
* @param treeid
* @param result
* @return
*/
public List getAllChildrenTrees(List source,String treeid,List result);
/**
* 取得一个节点的所有父节点
* 当前source中包含的元素结构为Map结构
* @param source
* @param treeid
* @param result
* @return
*/
public List getAllParentTrees(List source,String treeid,List result);
/**
* 当前source中包含的元素结构为Map结构
* 取得一个节点的直接父节点
* @param source
* @param treeid
* @return
*/
public Map getDirectParentTree(List source,String treeid);
/**
* 将Tree对像结构转化为统一的Map结构
* @return
*/
public List getTransedTrees();
/***
* 根据ID从集合中取得一个节点
* @param source
* @param treeid
* @return
*/
public Map getTree(List source, String treeid);
/**
* 如果节点是全集,根据ID取得一个节点
* 当前source中包含的元素结构为Map结构
* @param treeid
* @return
*/
public Map getTree(String treeid);
}
说明: 基本上每个方法都有说明了,结构规划的不是很好,还需要进一步调整. 如果要做功能更丰富的事,不妨再加上几个方法,到子类中实现 ,效果可能会更好一些,不过目前这个接口,基本功能可以满足了. 2.接着给出上面接口的实现类. package com.faceye.core.service.security.service.controller;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import com.faceye.core.service.controller.BaseHibernateService;
import com.faceye.core.service.security.dao.iface.ITreeDao;
import com.faceye.core.service.security.model.Tree;
import com.faceye.core.service.security.service.iface.ITreeService;
import com.faceye.core.util.helper.StringPool;
/**
*
* @author:宋海鹏
* @Connection:E_mail:ecsun@sohu.com/myecsun@hotmail.com QQ:82676683
* @Copy Right:www.faceye.com
* @System:www.faceye.com网络支持系统
* @Create Time:2007-9-22
* @Package com.faceye.core.service.security.service.controller.TreeService.java
* @Description:树形控制
*/
public class TreeService extends BaseHibernateService implements ITreeService {
private static List treeSource = null;
private static List transTreeSource = null;
public String treeJSON() {
// TODO Auto-generated method stub
try{
List trees = this.getTransedTrees();
String result = this.treeJSON(trees);
return result;
}catch(Exception e){
log.info(">>>>faceye error in method:treeJSON() is"+e.toString());
return null;
}
}
public String treeJSON(List source, String treeid) {
StringBuffer json = new StringBuffer();
if (StringUtils.isEmpty(treeid)) {
return json.toString();
} else {
List directChildrenTrees = this.getDirectChildrenTrees(source,
treeid);
if (directChildrenTrees != null && !directChildrenTrees.isEmpty()) {
json.append("[");
Iterator it = directChildrenTrees.iterator();
while (it.hasNext()) {
Map item = (Map) it.next();
json.append(this.transTree2JSON(source, item));
json.append(StringPool.CHARACTER_COMMA);
}
json.deleteCharAt(json.lastIndexOf(StringPool.CHARACTER_COMMA));
json.append("]");
}
}
return json.toString();
}
public String treeJSON(List source) {
// TODO Auto-generated method stub
if(source==null||source.isEmpty()){
return null;
}
List roots = this.getRoots(source);
Iterator it = roots.iterator();
StringBuffer json = new StringBuffer();
json.append("[");
while (it.hasNext()) {
Map item = (Map) it.next();
json.append(this.transTree2JSON(source, item));
json.append(",");
}
json.deleteCharAt(json.lastIndexOf(","));
json.append("]");
return json.toString();
}
public boolean isHaveParent(List source, String treeid) {
// TODO Auto-generated method stub
boolean result = false;
if (source == null || source.size() < 1) {
return result;
}
Map currentTree = this.getTree(source, treeid);
if (currentTree.get(StringPool.TREE_PARENTID) == null) {
result = false;
} else {
Map parentTree = this.getTree(source, currentTree.get(
StringPool.TREE_PARENTID).toString());
if (parentTree == null) {
result = false;
} else {
if (source.contains(parentTree)) {
result = true;
} else {
result = false;
}
}
}
return result;
}
public boolean isHaveParent(List source, Tree tree) {
// TODO Auto-generated method stub
boolean result = false;
if (!source.contains(tree)) {
return result;
} else {
if (tree.getParentTree() != null) {
result = true;
}
}
return result;
}
public boolean isHaveChildren(List source, Tree tree) {
// TODO Auto-generated method stub
boolean result = false;
if (tree.getChildrenTrees() != null
&& !tree.getChildrenTrees().isEmpty()) {
result = true;
}
return result;
}
/**
* 开发期间,树不加载入内存
* @return
*/
private List getTrees() {
//
// if (treeSource == null || treeSource.size() < 1) {
// treeSource = this.loadAllObjects(Tree.class);
// }
return this.loadAllObjects(Tree.class);
}
public List getTransedTrees() {
// return transTreeSource==null? this.transTrees(this.getTrees()):transTreeSource;
return this.transTrees(this.getTrees());
}
private Map transTree(Tree tree) {
Map result = new HashMap();
if (tree != null) {
result.put(StringPool.TREE_ID, tree.getId());
result.put(StringPool.TREE_NAME, tree.getName());
if (tree.getParentTree() != null) {
result.put(StringPool.TREE_PARENTID, tree.getParentTree()
.getId());
} else {
result.put(StringPool.TREE_PARENTID, null);
}
if(StringUtils.isNotEmpty(tree.getAction())){
result.put(StringPool.TREE_ACTION, tree.getAction());
}else{
result.put(StringPool.TREE_ACTION, null);
}
if(StringUtils.isNotEmpty(tree.getUrl())){
result.put(StringPool.TREE_URL, tree.getUrl());
}else{
result.put(StringPool.TREE_URL, null);
}
//result.put(StringPool.TREE_HREF_TARGET, "list-iframe");
}
return result;
}
private List transTrees(List source) {
List result = new ArrayList();
Iterator it = source.iterator();
while (it.hasNext()) {
Tree item = (Tree) it.next();
result.add(this.transTree(item));
}
return result;
}
public List getAllChildrenTrees(List source, String treeid, List result) {
// TODO Auto-generated method stub
List directChildrenTrees = this.getDirectChildrenTrees(source, treeid);
Map currentTree = this.getTree(source, treeid);
result.add(currentTree);
Iterator it = directChildrenTrees.iterator();
while (it.hasNext()) {
Map item = (Map) it.next();
if (this.isHaveParent(source, item)) {
this.getAllChildrenTrees(source, item.get(StringPool.TREE_ID)
.toString(), result);
} else {
result.add(item);
}
}
return result;
}
public List getAllParentTrees(List source, String treeid, List result) {
// TODO Auto-generated method stub
Map tree = this.getTree(source, treeid);
result.add(tree);
if (tree.get(StringPool.TREE_PARENTID) != null) {
if (this.getTree(source, tree.get(StringPool.TREE_PARENTID)
.toString()) != null) {
this.getAllParentTrees(source, tree.get(
StringPool.TREE_PARENTID).toString(), result);
}
}
return result;
}
public List getDirectChildrenTrees(List source, String treeid) {
// TODO Auto-generated method stub
List result = new ArrayList();
Iterator it = source.iterator();
while (it.hasNext()) {
Map item = (Map) it.next();
if (item.get(StringPool.TREE_PARENTID) != null) {
if (item.get(StringPool.TREE_PARENTID).toString().equals(treeid)) {
result.add(item);
}
}
}
return result;
}
public Map getDirectParentTree(List source, String treeid) {
// TODO Auto-generated method stub
Map reuslt = null;
Map tree = this.getTree(source, treeid);
if (tree.get(StringPool.TREE_PARENTID) != null) {
reuslt = this.getTree(source, tree.get(StringPool.TREE_PARENTID)
.toString());
}
return reuslt;
}
public List getRoots(List source) {
// TODO Auto-generated method stub
List result = new ArrayList();
Iterator it = source.iterator();
while (it.hasNext()) {
Map item = (Map) it.next();
if (!this.isHaveParent(source, item)) {
result.add(item);
}
}
return result;
}
public boolean isHaveChildren(List source, String treeid) {
// TODO Auto-generated method stub
boolean result = false;
if (source == null || source.isEmpty() || source.size() < 1
|| StringUtils.isEmpty(treeid)) {
return result;
}
Iterator it = source.iterator();
while (it.hasNext()) {
Map item = (Map) it.next();
if (item.get(StringPool.TREE_PARENTID) != null) {
if (item.get(StringPool.TREE_PARENTID).toString()
.equals(treeid)) {
result = true;
break;
}
}
}
return result;
}
/**
* ��ݽڵ�id���ؽڵ�
*
* @param source
* @param treeid
* @return
*/
public Map getTree(List source, String treeid) {
Map result = null;
if (source.isEmpty() || source.size() < 1
|| StringUtils.isEmpty(treeid)) {
return null;
}
Iterator it = source.iterator();
while (it.hasNext()) {
Map item = (Map) it.next();
if (item.get(StringPool.TREE_ID).toString().equals(treeid)) {
result = item;
break;
}
}
return result;
}
public Map getTree(String treeid) {
// TODO Auto-generated method stub
return this.getTree(this.getTransedTrees(), treeid);
}
public boolean isHaveParent(List source, Map transedTree) {
// TODO Auto-generated method stub
boolean result = false;
if (source.isEmpty() || source.size() < 1 || source == null
|| transedTree.isEmpty() || transedTree == null) {
return result;
} else {
if (transedTree.get(StringPool.TREE_PARENTID) == null) {
result = false;
} else {
Map parentTree = this.getTree(source, transedTree.get(
StringPool.TREE_PARENTID).toString());
if (parentTree.isEmpty() || parentTree == null) {
result = false;
} else {
if (source.contains(parentTree)) {
result = true;
} else {
result = false;
}
}
}
}
return result;
}
private String transTree2JSON(List source, Map tree) {
StringBuffer json = new StringBuffer();
json.append("{");
json.append("\"text\":");
json.append("\"");
json.append(tree.get(StringPool.TREE_NAME).toString());
json.append("\"");
json.append(",");
json.append("\"id\":");
json.append("\"");
json.append(tree.get(StringPool.TREE_ID).toString());
json.append("\"");
json.append(",");
json.append("\"leaf\":");
if (this
.isHaveChildren(source, tree.get(StringPool.TREE_ID).toString())) {
json.append("false");
} else {
json.append("true");
}
json.append(",");
json.append("\"cls\":");
json.append("\"file\"");
if(tree.get(StringPool.TREE_ACTION)!=null){
json.append(",");
json.append("\"link\":");
json.append("\"");
json.append(tree.get(StringPool.TREE_ACTION).toString());
json.append("\"");
//link target
// json.append(",");
// json.append("\"hrefTarget\":");
// json.append("\"");
// json.append(tree.get(StringPool.TREE_HREF_TARGET).toString());
// json.append("\"");
}else{
json.append(",");
json.append("\"link\":");
json.append("\"");
json.append("#");
json.append("\"");
}
json.append("}");
return json.toString();
}
}
说明: 处理树形结构不可避免的要用到递归结构,没有办法的事情,在这里我们可以做一此类似缓存的处理,这样子,就不用过分的去查询数据库了. 我个人比较反对每判断一个节点是否有父节点或是否有子节点或是有多少个子节点,或是拿出其所有的子节点,或是拿出其所有的父节点都去查询一次数据库,毕竟,查询数据库性能损耗还是很大的.虽然在oracle和sql server 的新版中,提供了这个递归查询,但能不用,我觉得还是不用,毕竟,树的操作,在一个系统中,是很频繁的,因为一个树的操作,给数据库带来不必的要压力,个人感觉,有些不太好. 以上就是后台的大部分代码 明天还有一个收尾工作,就要要把这些数据,传到前台去展现. 今天先写到这里,明天再写了. 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
最后更新时间:2008-01-23
老大:
你的树的数据库结构是什么样子的?能否给个oracle版本的例子? |
|
| 返回顶楼 | |
|
最后更新时间:2008-01-23
在上一篇中有提及:
http://www.javaeye.com/topic/158206 blog: http://ecsun.javaeye.com |
|
| 返回顶楼 | |
|
最后更新时间:2008-03-04
使用jsonlib会帮你省不少事,或改用struts2,他默认对支持json,只要加入几个jar,辛苦了!!!!
|
|
| 返回顶楼 | |
|
最后更新时间:2008-04-02
json lib并不能解决所有问题,比如有父子对像映射相关
|
|
| 返回顶楼 | |
|
最后更新时间:2008-04-06
我是搞NET的,看不明白你的,有没有NET版本的啊?/
|
|
| 返回顶楼 | |
|
最后更新时间:2008-04-15
树型结构的设计, 可以通过记录结构的全路径来解决递归操作, 效率上可以一个数量级的提高
|
|
| 返回顶楼 | |
|
最后更新时间:2008-04-16
建议参考下 e3.tree (javaeye)搜索e3.tree 可以找到,非常不错。
|
|
| 返回顶楼 | |


![ecsun的博客: [海鹏Blog]--{FaceYe开源} 用户头像](http://www.javaeye.com/upload/logo/user/36668/bcfaff38-8200-4288-88e6-f588c3138e36.gif?1196653519)





