1. 程式人生 > >後臺系統開發

後臺系統開發

後臺管理系統工程

1、採用maven構建專案

  • Maven定義了軟體開發的整套流程體系,並進行了封裝,開發人員只需要指定專案的構建流程,無需針對每個流程編寫自己的構建指令碼。除了專案構建,Maven最核心的功能是軟體包的依賴管理,能夠自動分析專案所需要的依賴軟體包,併到Maven中心倉庫去下載。並統一管理依賴的jar包。和工程之間的依賴關係。
  • 使用Maven的本地倉庫:
    在當前系統使用者的資料夾下。例如當前使用者是Administrator那麼本地倉庫就是在C:\Users\Administrator.m2目錄下。若要自定義倉庫位置只需要修改Maven的配置檔案即可。關於Maven的更多介紹可以參考這裡。
    點我
  • Maven外掛使用eclipse mars自帶maven外掛。只需要統一開發環境。

2、建立工程

  • 後臺系統專案依賴關係

enjoyshop-parent 管理依賴jar包的版本,全域性,公司級別,pom資訊如下:

    <groupId>com.enjoyshop.parent</groupId>
    <artifactId>enjoyshop-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>
pom</packaging>

enjoyshop-common –通用元件、工具類

    <parent>
        <groupId>com.enjoyshop.parent</groupId>
        <artifactId>enjoyshop-parent</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <groupId>com.enjoyshop.common</groupId
>
<artifactId>enjoyshop-common</artifactId> <version>1.0.0-SNAPSHOT</version>

enjoyshop-manage –後臺系統

    <parent>
        <groupId>com.enjoyshop.parent</groupId>
        <artifactId>enjoyshop-parent</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <groupId>com.enjoyshop.manage</groupId>
    <artifactId>enjoyshop-manage</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <modules>
        <module>enjoyshop-manage-pojo</module>
        <module>enjoyshop-manage-mapper</module>
        <module>enjoyshop-manage-service</module>
        <module>enjoyshop-manage-web</module>
    </modules>

    <dependencies>
        <dependency>
            <groupId>com.enjoyshop.common</groupId>
            <artifactId>enjoyshop-common</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>
        <!--省略了其他資訊-->
    </dependencies>

enjoyshop.manage.pojo

    <parent>
        <groupId>com.enjoyshop.manage</groupId>
        <artifactId>enjoyshop-manage</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <artifactId>enjoyshop-manage-pojo</artifactId>

enjoyshop.manage.mapper

    <parent>
        <groupId>com.enjoyshop.manage</groupId>
        <artifactId>enjoyshop-manage</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <artifactId>enjoyshop-manage-mapper</artifactId>
    <dependencies>
        <dependency>
            <groupId>com.enjoyshop.manage</groupId>
            <artifactId>enjoyshop-manage-pojo</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>
        <!--省略了其他資訊-->
    </dependencies>

enjoyshop.manage.service

    <parent>
        <groupId>com.enjoyshop.manage</groupId>
        <artifactId>enjoyshop-manage</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <artifactId>enjoyshop-manage-service</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.enjoyshop.manage</groupId>
            <artifactId>enjoyshop-manage-mapper</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>
        <!--省略了其他資訊-->
    </dependencies>

enjoyshop.manage.web

    <parent>
        <groupId>com.enjoyshop.manage</groupId>
        <artifactId>enjoyshop-manage</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <artifactId>enjoyshop-manage-web</artifactId>
    <packaging>war</packaging>

    <dependencies>
        <dependency>
            <groupId>com.enjoyshop.manage</groupId>
            <artifactId>enjoyshop-manage-service</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>
        <!--省略了其他資訊-->
    </dependencies>
  • 匯入依賴和tomcat外掛

匯入依賴的原則:
1、在使用依賴的最底層匯入。
2、執行時所需要的依賴在web工程中加入。
3、所有的工程都需要的依賴應該在聚合工程(enjoyshop-manage)中匯入。
匯入SSM依賴:
Spring和SpringMVC的依賴在enjoysho-manage-service中匯入;
匯入tomcat外掛:
聚合工程的tomcat外掛要在聚合工程中匯入,enjoysho-manage中匯入。

    <build>
        <plugins>
            <!-- 配置Tomcat外掛 -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <configuration>
                    <port>8081</port>
                    <path>/</path>
                </configuration>
            </plugin>
        </plugins>
    </build>

3、初步整合SSM

  • 在enjoyshop.manage.web專案的相應目錄下建立web.xml檔案
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>enjoyshop-manage</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/applicationContext*.xml</param-value>
    </context-param>

    <!--Spring的ApplicationContext 載入 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- 編碼過濾器,以UTF8編碼 -->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 解決PUT請求無法提交表單資料的問題 -->
    <filter>
        <filter-name>HttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 將POST請求轉化為DELETE或者是PUT 要用_method指定真正的請求引數 -->
    <filter>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>


    <!-- 配置SpringMVC框架入口 -->
    <servlet>
        <servlet-name>enjoyshop-manage</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/enjoyshop-manage-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>enjoyshop-manage</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

</web-app>
  • 加入Sping的配置檔案

applicationContext.xml(spring關於Bean的配置檔案)

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

    <!-- 使用spring自帶的佔位符替換功能 -->
    <bean
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <!-- 允許JVM引數覆蓋 -->
        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
        <!-- 忽略沒有找到的資原始檔 -->
        <property name="ignoreResourceNotFound" value="true" />
        <!-- 配置資原始檔 -->
        <property name="locations">
            <list>
                <value>classpath:jdbc.properties</value>
            </list>
        </property>
    </bean>

    <!-- 掃描包 -->
    <context:component-scan base-package="com.enjoyshop"/>

     <!-- 定義資料來源 -->
    <bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource"
        destroy-method="close">
        <!-- 資料庫驅動 -->
        <property name="driverClass" value="${jdbc.driverClassName}" />
        <!-- 相應驅動的jdbcUrl -->
        <property name="jdbcUrl" value="${jdbc.url}" />
        <!-- 資料庫的使用者名稱 -->
        <property name="username" value="${jdbc.username}" />
        <!-- 資料庫的密碼 -->
        <property name="password" value="${jdbc.password}" />
        <!-- 檢查資料庫連線池中空閒連線的間隔時間,單位是分,預設值:240,如果要取消則設定為0 -->
        <property name="idleConnectionTestPeriod" value="60" />
        <!-- 連線池中未使用的連結最大存活時間,單位是分,預設值:60,如果要永遠存活設定為0 -->
        <property name="idleMaxAge" value="30" />
        <!-- 每個分割槽最大的連線數 -->
        <!-- 
            判斷依據:請求併發數
         -->
        <property name="maxConnectionsPerPartition" value="100" />
        <!-- 每個分割槽最小的連線數 -->
        <property name="minConnectionsPerPartition" value="5" />
    </bean>

</beans>

applicationContext-transaction.xml(Spring關於事務的配置檔案)

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

    <!-- 定義事務管理器 -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!-- 定義事務策略 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!--所有以query開頭的方法都是隻讀的 -->
            <tx:method name="query*" read-only="true" />
            <!--其他方法使用預設事務策略 -->
            <tx:method name="*" />
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <!--pointcut元素定義一個切入點,execution中的第一個星號 用以匹配方法的返回型別,這裡星號表明匹配所有返回型別。 -->
        <aop:pointcut id="myPointcut" expression="execution(* com.enjoyshop.manage.service.*.*(..))" />
        <!--將定義好的事務處理策略應用到上述的切入點 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut" />
    </aop:config>

</beans>
  • 加入SpringMVC的配置檔案

enjoyshop-manage-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <!-- 定義註解驅動 -->
    <mvc:annotation-driven/>

    <!-- 定義Controller的掃描包 -->
    <context:component-scan base-package="com.enjoyshop.manage.controller"/>

    <!-- 定義試圖解析器 -->
    <!-- 
        Example: prefix="/WEB-INF/jsp/", suffix=".jsp", viewname="test" -> "/WEB-INF/jsp/test.jsp" 
     -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

</beans>
  • 加入Mybatis的配置檔案

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <plugins>
        <!-- 配置分頁助手 -->
        <plugin interceptor="com.github.pagehelper.PageHelper">
            <property name="dialect" value="mysql" />
            <!-- 設定為true時,使用RowBounds分頁會進行count查詢 -->
            <property name="rowBoundsWithCount" value="true" />
        </plugin>

        <!-- 通用Mapper -->
        <plugin interceptor="com.github.abel533.mapperhelper.MapperInterceptor">
            <!--主鍵自增回寫方法,預設值MYSQL,詳細說明請看文件 -->
            <property name="IDENTITY" value="MYSQL" />
            <!--通用Mapper介面,多個通用介面用逗號隔開 -->
            <property name="mappers" value="com.github.abel533.mapper.Mapper" />
        </plugin>
    </plugins>

</configuration>
  • 關於SSM整合可以參考這裡。點我
  • 關於分頁助手和通用Mapper可以參考這裡。點我

4、匯入資料庫資料

關於資料庫設計可以參考這裡。點我
也可以直接到資料庫SQL這個目錄下找到SQL指令碼。

5、實現頁面的通用跳轉

package com.enjoyshop.manage.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@RequestMapping("page")//這個類攔截類似/page/*這種請求
@Controller  //標記為一個controller
public class PageController {
    @RequestMapping(value = "{pageName}", method = RequestMethod.GET)
    public String toPage(@PathVariable("pageName") String pageName) {
        return pageName;
    }

}
@RequestMapping(value = "{pageName}", method = RequestMethod.GET)

這行程式碼註解表示toPage這個方法接受一個佔位符引數pageName(用大括號擴起來的就是佔位符引數),並且指定了這個方法只響應GET請求。之後toPage通過
(@PathVariable("pageName") String pageName
這種形式來接受佔位符引數,並把這個值賦給方法的輸入引數pageName。
綜合分析,如果請求的URL是/rest/page/index.jsp,那麼首先SpringMVC會攔截/rest/*的請求,之後交給這個類來處理。此時傳給toPage方法的佔位符引數是“index”,那麼該方法也就返回“index”這個字串,經過springMVC解析後,返回WEB-INF/views/index.jsp這個檢視。

6、登入邏輯的實現

  • URL:rest/page/login.jsp
  • 處理邏輯:
    <script type="text/javascript">
        $("#login").click(function(){
            var username = $("[name=username]").val();
            var password = $("[name=password]").val();

            if(username!="admin" || password!="admin"){
                $.messager.alert('錯誤',"使用者名稱密碼不正確!");
                return ;
            }
            window.location.href="/rest/page/index";
        });
    </script>

這裡簡化了使用者登入的功能,直接檢測使用者名稱和密碼是否為“admin”。在實際應用中應當連線資料庫進行查詢再返回結果。

7、首頁選單樹的實現

  • URL:rest/page/index.jsp
<body class="easyui-layout">
    <div data-options="region:'west',title:'選單',split:true" style="width:180px;">
        <ul id="menu" class="easyui-tree" style="margin-top: 10px;margin-left: 5px;">
            <li>
                <span>商品管理</span>
                <ul>
                    <li data-options="attributes:{'url':'/rest/page/item-add'}">新增商品</li>
                    <li data-options="attributes:{'url':'/rest/page/item-list'}">查詢商品</li>
                    <li data-options="attributes:{'url':'/rest/page/item-param-list'}">規格引數</li>
                </ul>
            </li>
            <li>
                <span>網站內容管理</span>
                <ul>
                    <li data-options="attributes:{'url':'/rest/page/content-category'}">內容分類管理</li>
                    <li data-options="attributes:{'url':'/rest/page/content'}">內容管理</li>
                </ul>
            </li>
         </ul>
    </div>
    <div data-options="region:'center',title:''">
        <div id="tabs" class="easyui-tabs">
            <div title="首頁" style="padding:20px;">

            </div>
        </div>
    </div>

首頁的佈局通過easyui-layout來實現,而左側選單是通過定義一個easyui-tree來實現。

<ul id="menu" class="easyui-tree" style="margin-top: 10px;margin-left: 5px;">
  • 選單點選事件
<script type="text/javascript">
$(function(){
    $('#menu').tree({
        onClick: function(node){//node是點選的節點物件
            if($('#menu').tree("isLeaf",node.target)){//判斷當前節點是不是葉子節點,若是父節點則不作處理
                var tabs = $("#tabs");
                var tab = tabs.tabs("getTab",node.text);//通過葉子節點的名稱查詢tab
                if(tab){//tab已存在,表示頁面已開啟,則選中開啟的tab
                    tabs.tabs("select",node.text);
                }else{
                    tabs.tabs('add',{
                        title:node.text,
                        href: node.attributes.url,
                        closable:true,
                        bodyCls:"content"
                    });
                }
            }
        }
    });
});

8、顯示商品類目的功能實現

  • 功能描述:在新增商品時點選選擇類目,彈出視窗,在視窗中顯示商品類目資料。
  • 點選按鈕描述
            <tr>
                <td>商品類目:</td>
                <td>
                    <a href="javascript:void(0)" class="easyui-linkbutton selectItemCat">選擇類目</a>
                    <input type="hidden" name="cid" style="width: 280px;"></input>
                </td>
            </tr>

class="easyui-linkbutton selectItemCat
指明瞭這個按鈕的屬性是一個easyui-linkbutton,關聯的點選事件是selectItemCat。而這個selectItemCat的定義在common.js中。

  • 點選彈出視窗的實現
// 初始化選擇類目元件
    initItemCat : function(data){
        //i代表index索引,表示第幾個元素
        //e代表element元素
        $(".selectItemCat").each(function(i,e){
            var _ele = $(e);//把dom物件轉為JQuery物件
            if(data && data.cid){
                _ele.after("<span style='margin-left:10px;'>"+data.cid+"</span>");
            }else{
                _ele.after("<span style='margin-left:10px;'></span>");
            }
            _ele.unbind('click').click(function(){//解綁事件再繫結事件,可以防止重複繫結(繫結之前清除所有其他繫結)
                $("<div>").css({padding:"5px"}).html("<ul>")//$("<div>")表示建立一個div,.css表示給予樣式,.html寫入ul元素
                .window({
                    width:'500',
                    height:"450",
                    modal:true,
                    closed:true,
                    iconCls:'icon-save',
                    title:'選擇類目',
                    onOpen : function(){//視窗開啟時執行
  • 載入並顯示商品類目資料
 onOpen : function(){//視窗開啟時執行
                        var _win = this;//this指的是$("<div>")
                        $("ul",_win).tree({//$("ul",_win)表示在$("<div>")下去查詢ul元素
                            url:'/rest/item/cat',
                            animate:true,
                            method:"GET",
                            onClick : function(node){
                                if($(this).tree("isLeaf",node.target)){
                                    // 填寫到cid中
                                    _ele.parent().find("[name=cid]").val(node.id);//設定隱藏框的值為節點id
                                    _ele.next().text(node.text).attr("cid",node.id);
                                    $(_win).window('close');
                                    if(data && data.fun){
                                        data.fun.call(this,node);
                                    }
                                }
                            }
                        });
                    },
                    onClose : function(){//視窗關閉事件
                        $(this).window("destroy");
                    }
  • 在item-add.jsp上的初始化
    以上的事件函式定義在一個名為ENJOYSHOP的物件中
var TT = ENJOYSHOP = {
·····
 // 初始化選擇類目元件
    initItemCat : function(data){
    ······
    }
}

然後再jsp頁面上通過ENJOYSHOP.ini的方法實現初始化和載入。

$(function(){
        itemAddEditor = ENJOYSHOP.createEditor("#itemAddForm [name=desc]");
        ENJOYSHOP.init({fun:function(node){
            ENJOYSHOP.changeItemParam(node, "itemAddForm");
        }});
    });

最後在TT.init中呼叫initItemCat方法,給class=”selectItemCat”繫結click事件,即可實現效果。

  • 編寫商品類目的POJO類

首先編寫一個BasePojo類,存放一些基礎通用資料。

package com.enjoyshop.manage.pojo;

import java.util.Date;

public abstract class BasePojo {

    private Date created;
    private Date updated;
    public Date getCreated() {
        return created;
    }
    public void setCreated(Date created) {
        this.created = created;
    }
    public Date getUpdated() {
        return updated;
    }
    public void setUpdated(Date updated) {
        this.updated = updated;
    }



}

編寫ItemCat類,繼承BasePojo

package com.enjoyshop.manage.pojo;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Table(name = "tb_item_cat")
public class ItemCat extends BasePojo {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private Long parentId;

    private String name;