後臺系統開發
後臺管理系統工程
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>
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;