首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

樹狀結構實戰:基於 MyBatis + Spring + zTree 的機構樹完整實作

     編輯:Java 綜合教學

專案背景與技術棧

  • 框架:MyBatis + Spring + zTree (jQuery 樹插件) + zDialog
  • 目標:實現機構樹的查詢、展示、選取回填
  • 核心思路:先抽象樹節點模型,再分層實作 DAO、Service、Controller、前端頁面

效果預覽

機構樹效果圖

一、樹節點資料模型 (TreeModel)

package com.dyl.dto;
import java.io.Serializable;

public class TreeModel implements Serializable {
    private String id;       // 節點 id
    private String pId;      // 父節點 id (zTree 必須大寫 P)
    private String name;     // 節點名稱
    private boolean open = false; // 預設不展開
    private String url;      // 連結目標 URL
    private String icon;     // 自訂圖標路徑
    private String title;    // 提示訊息
    // Getter/Setter 省略...
}

關鍵點:pId 大寫 P 為 zTree 固定慣例;title 欄位作為節點顯示文字(含 id+name)。

二、Spring + MyBatis 整合配置

web.xml

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:context/springContext-*.xml</param-value>
</context-param>
<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<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>

jdbc.properties

jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:ORCL
jdbc.username=dyl
jdbc.password=dyl

springContext-datasource.xml

<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"/>
</bean>

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  <property name="dataSource" ref="dataSource"/>
  <property name="configLocation" value="classpath:sqlmap/mybatis-config.xml"/>
</bean>

<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"/>

mybatis-config.xml

<typeAliases>
  <typeAlias alias="tree" type="com.dyl.dto.TreeModel"/>
</typeAliases>
<mappers>
  <mapper resource="com/dyl/dao/OrgDaoMapper.xml"/>
</mappers>

三、資料存取層 (DAO)

介面

public interface IOrgDao {
    List getTreeList(String org);
}

Mapper XML (Oracle 層次查詢)

<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>

使用 Oracle START WITH ... CONNECT BY 遞歸查詢,nocycle 防循環。

四、業務邏輯層 (Service)

@Service("orgServiceImpl")
@Transactional
public class OrgServiceImpl implements IOrgService {
    @Resource(name="sqlSessionTemplate")
    private SqlSessionTemplate session;

    public List getTreeList(String org) throws Exception {
        IOrgDao dao = session.getMapper(IOrgDao.class);
        return dao.getTreeList(org);
    }
}

五、控制層 (Controller)

@Controller
@RequestMapping("org.do")
public class OrgController {
    @Resource(name="orgServiceImpl")
    private IOrgService orgService;

    @RequestMapping(params="method=queryOrg")
    public void queryOrg(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("text/html;charset=GBK");
        PrintWriter out = response.getWriter();
        String data = "0"; // 預設失敗

        try {
            List list = orgService.getTreeList(request.getParameter("org"));
            if (list.isEmpty()) data = "2"; // 無資料
            else data = JSONArray.fromObject(list).toString();
        } catch (Exception e) {
            logger.error("查詢機構樹異常", e);
        } finally {
            out.write(data);
            out.close();
        }
    }
}

六、前端頁面與 zTree 整合

父頁面:彈窗呼叫樹頁面

function selectOrg() {
    var diag = new Dialog();
    diag.Width = 400; diag.Height = 400;
    diag.Title = "請選擇機構";
    diag.URL = '/WebRoot/jsp/invoicemanage/invoiceOrgTree.jsp?org=' + fm.org.value;
    diag.OKEvent = function() {
        var val = diag.innerFrame.contentWindow.document.getElementById('orgOfTree').value;
        if (val) { fm.org.value = val; diag.close(); }
        else Dialog.alert('請選擇機構');
    };
    diag.show();
}

樹頁面:invoiceOrgTree.jsp

<script src="/WebRoot/js/jquery-1.9.1.min.js"></script>
<script src="/WebRoot/js/zTree/jquery.ztree.all.min.js"></script>
<link rel="stylesheet" href="/WebRoot/js/zTree/zTreeStyle.css"/>

<ul id="orgTree" class="ztree"></ul>

<script>
function init() {
    $.ajax({
        type: "POST", url: '/WebRoot/org.do',
        data: { method: 'queryOrg', org: fm.orgOfTree.value },
        dataType: "json",
        beforeSend: function() { $(document).mask('載入中...'); },
        success: function(data) {
            if (data == '0') { Dialog.alert('系統異常'); return; }
            if (data == '2') { Dialog.alert('無資料'); return; }

            var setting = {
                check: { chkStyle: 'radio', radioType: 'all' },
                data: { key: { name: 'title' }, simpleData: { enable: true } },
                callback: { onClick: zTreeOnClick, onCheck: zTreeOnCheck }
            };
            var treeNodes = data; // 後端直接回傳 zTree 相容的簡單 JSON
            $.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;
            }
        },
        complete: function() { $(document).unmask(); }
    });
}

function zTreeOnClick(event, treeId, treeNode) {
    fm.orgOfTree.value = treeNode.id;
}
function zTreeOnCheck(event, treeId, treeNode) {
    fm.orgOfTree.value = treeNode.id;
}
</script>

七、專案結構圖

代碼結構圖

總結

本實作展示了從資料庫層次查詢、DTO 設計、MyBatis 映射、Spring 分層、Controller JSON 回傳、zTree 前端渲染的完整鏈路。關鍵在於後端直接輸出 zTree 相容的簡單 JSON 格式,前端零轉換即可渲染,極大簡化開發。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved