想实现一下“树型结构”,提供一种实现思路,实践方法为先主干后细节,此处只写主干思路。
1、先看效果图:
实现框架为:mybatis + spring + zTree + zDialog;
2、根据页面元素,及zTree前台框架,抽象出树型结构对象,用于接收后台的数据库数据,方便使用java对象,传输数据信息到前台页面。
注:面向对象编程的思想,多用几次就有了。
import java.io.Serializable;
/**
* 树查询结果类
*
* @author duyaolin
* @date 2016-6-1 下午04:26:21
*/
public class TreeModel implements Serializable {
private static final long serialVersionUID = -3975150427085854588L;
private String id;// 节点id
private String pId;// 父节点pId,I必须大写
private String name;// 节点名称
private boolean open = false;// 是否展开树节点,默认不展开
private String url;// 节点链接的目标URL
private String icon;// 节点自定义图标的URL路径
private String title;// 节点提示信息
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getpId() {
return pId;
}
public void setpId(String pId) {
this.pId = pId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isOpen() {
return open;
}
public void setOpen(boolean open) {
this.open = open;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
View Code
3、配置web.xml、jdbc.properties、springContext-*.xml、mybatis-config.xml。
<!-- 加载Spring容器配置 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 设置Spring容器加载配置文件路径 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:context/springContext-*.xml</param-value>
</context-param>
<!-- Spring请求分发servlet -->
<servlet>
<servlet-name>SpringServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:context/dispatcher_servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>SpringServlet</servlet-name>
<url-pattern>*.doo</url-pattern>
</servlet-mapping>
<!-- 解决工程编码过滤器 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
View Code
View Code
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<!-- 读取属性文件 -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>
<!-- 配置DataSource数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >
<property name="driverClassName" value="{jdbc.driverClassName}" />
<property name="url" value="{jdbc.url}" />
<property name="username" value="{jdbc.username}" />
<property name="password" value="{jdbc.password}" />
<property name="initialSize" value="1" />
<property name="maxActive" value="5" />
<property name="maxIdle" value="2" />
<property name="minIdle" value="1" />
<property name="maxWait" value="-1" />
<property name="timeBetweenEvictionRunsMillis" value="20000" />
<property name="minEvictableIdleTimeMillis" value="10000" />
<property name="defaultAutoCommit" value="false" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:sqlmap/mybatis-config.xml" />
</bean>
<!-- SESSION模板 -->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
View Code
<configuration>
<settings>
<!-- changes from the defaults -->
<setting name="lazyLoadingEnabled" value="false" />
</settings>
<!-- Register Alias -->
<typeAliases>
<typeAlias alias="org" type="com.dyl.dto.OrgDto" />
<typeAlias alias="emp" type="com.dyl.dto.EmpDto" />
<typeAlias alias="tree" type="com.dyl.dto.TreeModel" />
</typeAliases>
<!-- Register Mapper -->
<mappers>
<mapper resource="com/dyl/dao/EmpDaoMapper.xml" />
<mapper resource="com/dyl/dao/OrgDaoMapper.xml" />
</mappers>
</configuration>
View Code
4、编写数据层。
import java.util.List;
import com.dyl.dto.TreeModel;
public interface IOrgDao {
public List<TreeModel> getTreeList(String org);
}
View Code
<select id="getTreeList" parameterType="java.lang.String" resultType="tree">
select distinct comcode id, comcname name, uppercomcode pId, (comcode || '-' || comcname) title, comlevel from org
start with comcode like concat(#{org}, '%') connect by nocycle uppercomcode = prior comcode order by comlevel
</select>
</mapper>
View Code
5、编写业务层。
import java.util.List;
import com.dyl.dto.TreeModel;
public interface IOrgService {
// 获取机构树信息
public List<TreeModel> getTreeList(String org) throws Exception;
}
View Code
import java.util.List;
import javax.annotation.Resource;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.dyl.dao.IOrgDao;
import com.dyl.dto.TreeModel;
import com.dyl.service.IOrgService;
@Transactional
@Service("orgServiceImpl")
public class OrgServiceImpl implements IOrgService{
@Resource(name="sqlSessionTemplate")
private SqlSessionTemplate session;
public List<TreeModel> getTreeList(String org) throws Exception {
IOrgDao orgDao = session.getMapper(IOrgDao.class);
List<TreeModel> list = orgDao.getTreeList(org);
return list;
}
}
View Code
6、编写控制器。
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import com.dyl.dto.TreeModel;
import com.dyl.service.IOrgService;
@Controller
@RequestMapping("org.do")
public class OrgController {
Logger logger = Logger.getLogger(this.getClass());
@Resource(name = "orgServiceImpl")
private IOrgService orgService;
// 选择机构
@RequestMapping(params = "method=queryOrg")
public void queryOrg(HttpServletRequest request,
HttpServletResponse response, ModelMap model) throws IOException {
String data = "";// 返回标识到客户端,"0"-后台处理失败(系统异常)
response.setContentType("text/html;charset=GBK");// 让浏览器用GBK来解析返回的数据
PrintWriter printWriter = response.getWriter();
try {
List<TreeModel> treeList = orgService.getTreeList(request.getParameter("org"));
if (treeList.size() == 0) {
data = "2";// 没有数据
} else {
data = JSONArray.fromObject(treeList).toString();
}
} catch (Exception e) {
data = "0";
logger.error("获取机构树信息出现异常", e);
}
printWriter.write(data);
printWriter.close();
}
}
View Code
7、父页面核心代码。
function selectOrg() {
var org = fm.org.value;
var url = '/WebRoot/jsp/invoicemanage/invoiceOrgTree.jsp?org=' + org;
var diag = new Dialog();
diag.Width = 400;
diag.Height = 400;
diag.Title = "请选择机构";
diag.ShowButtonRow = true;
diag.OKEvent = function() {
var orgOfTree = diag.innerFrame.contentWindow.document.getElementById('orgOfTree').value;
if (orgOfTree && orgOfTree != '') {
fm.org.value = orgOfTree;
diag.close();
} else {
Dialog.alert('<span style="color:red;"><b>受票机构</b></span>不允许为空');
}
};
diag.URL = url;
diag.show();
diag.okButton.value = "确 定";
diag.cancelButton.value = "取 消";
}
View Code
8、编写树型结构页面。
<html>
<head>
<title>机构树</title>
<link rel="stylesheet" type="text/css" href="/WebRoot/css/standard.css">
</head>
<body onload="init('rLike')" background="/WebRoot/images/bgCommon.gif">
<form name="fm" method="POST" action="">
<table cellpadding="5" cellspacing="1">
<tr>
<td>机构:</td>
<td>
<input type="text" id="orgOfTree" name="orgOfTree" class="codecode" maxLength="10"
style="width: 100px;" value="<%=org %>" ondblclick="init('rLike');">
</td>
</tr>
</table>
<ul id="orgTree" class="ztree">
</ul><br/>
</form>
</body>
<script type="text/javascript" src="/WebRoot/js/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="/WebRoot/js/zDialog/zDrag.js"></script>
<script type="text/javascript" src="/WebRoot/js/zDialog/zDialog.js"></script>
<script type="text/javascript" src="/WebRoot/js/mask.js"></script>
<link rel="stylesheet" type="text/css" href="/WebRoot/js/zTree/zTreeStyle.css">
<script type="text/javascript" src="/WebRoot/js/zTree/jquery.ztree.all.min.js"></script>
<script type="text/javascript">
var orgOfTree = fm.orgOfTree.value;
function init(flag) {// flag为模糊查询标志
(function() {
alert("jQuery oK!");
});
.ajax( {
type : "POST",
url : '/WebRoot/org.do',
data : {
method : 'queryOrg',
org : fm.orgOfTree.value
},
dataType : "json",
beforeSend : function() {
(document).mask('系统正在处理中,请稍后...');
},
success : function(data) {
if ('0' == data) {
Dialog.alert('<span style="color:red;"><b>获取机构树异常,请联系管理员!</b></span>', function() {
Dialog.close();
});
} else if ('2' == data) {
Dialog.alert('<span style="color:red;"><b>没有找到机构,请重新输入!</b></span>');
} else {
var setting = {
callback : {
onCheck: zTreeOnCheck,
onClick: zTreeOnClick
},
check : {
chkStyle : 'radio',
//enable : true,
radioType : 'all'
},
data : {
key : {
name : 'title'
},
simpleData : {
enable : true
}
}
};
var treeNodes = data;// 把后台封装好的简单Json格式赋给treeNodes
(function() {
.fn.zTree.init(("#orgTree"), setting, treeNodes);
});
var treeObj = .fn.zTree.getZTreeObj("orgTree");
var nodes = treeObj.getNodes();
if (nodes.length > 0) {
treeObj.selectNode(nodes[0]);
fm.orgOfTree.value = nodes[0].id;
//fm.orgNameOfTree.value = nodes[0].name;
}
}
},
error : function(XMLResponse) {// 用于调试错误
alert(XMLResponse.responseText);
},
complete : function() {
(document).unmask();
}
});
}
// 用于捕获checkbox/radio被勾选或取消勾选的事件回调函数
function zTreeOnCheck(event, treeId, treeNode) {
fm.orgOfTree.value = treeNode.id;
//fm.orgNameOfTree.value = treeNode.name;
}
// 用于捕获节点被点击的事件回调函数
function zTreeOnClick(event, treeId, treeNode) {
fm.orgOfTree.value = treeNode.id;
//fm.orgNameOfTree.value = treeNode.name;
};
</script>
</html>
View Code
9、最后,附上代码结构图。
注:本次实践是常见工具库的调用,也花了两个半小时,想出来、做出来、说出来、写出来,是不一样的。完。