上一章我們將RMS後臺管理系統搭建完畢,本章我們就在這個系統上實現錄入遊戲配置的功能。目前我們需要配置四項,每個等級的人物屬性,每個等級的升級經驗,遊戲地圖,地圖中的怪物。下面我們以遊戲地圖配置為例子,實現對它的增刪查改功能。
一、資料訪問層的實現
首先,我們需要定義地圖類,這個類在各個模組通用,因此要定義在facade模組中。我們新建一個包com.idlewow.map.model,在其中新建WowMap類,程式碼如下:
package com.idlewow.map.model; import com.idlewow.common.model.BaseModel; import lombok.Data; import java.io.Serializable; @Data public class WowMap extends BaseModel implements Serializable { private String name; private Integer occupy; private String description; }
然後,我們在core模組中實現資料訪問層的邏輯。新建com.idlewow.map.mapper包,並新建一個介面類WowMapMapper,在介面中定義我們需要用到的一些增刪查改方法,程式碼如下:
package com.idlewow.map.mapper; import com.idlewow.map.model.WowMap; import com.idlewow.query.model.WowMapQueryParam; import java.util.List; public interface WowMapMapper { int insert(WowMap wowMap); int batchInsert(List<WowMap> list); int update(WowMap levelProp); int delete(String id); WowMap find(String id); List<WowMap> list(WowMapQueryParam queryParam); int count(WowMapQueryParam queryParam); }
Mapper介面類,只定義了方法,具體實現需要我們在該包下新建一個WowMapMapper.xml檔案,在這個檔案中,通過SQL語句實現介面中的方法:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.idlewow.map.mapper.WowMapMapper"> <resultMap id="BaseResultMap" type="com.idlewow.map.model.WowMap"> <result column="id" property="id"/> <result column="name" property="name"/> <result column="occupy" property="occupy"/> <result column="description" property="description"/> <result column="create_user" property="createUser"/> <result column="update_user" property="updateUser"/> <result column="create_time" property="createTime"/> <result column="update_time" property="updateTime"/> <result column="is_delete" property="isDelete"/> <result column="version" property="version"/> </resultMap> <!-- 新增 --> <insert id="insert"> insert into map (name, occupy, description, create_user) values (#{name}, #{occupy}, #{description}, #{createUser}) </insert> <!-- 批量新增 --> <insert id="batchInsert"> insert into map (name, occupy, description, create_user) values <foreach collection="list" item="item" separator=","> (#{item.name}, #{item.occupy}, #{item.description}, #{item.createUser}) </foreach> </insert> <!-- 修改 --> <update id="update"> update map set name = #{name}, occupy = #{occupy}, description = #{description}, update_user = #{updateUser}, version = version + 1 where id = #{id} and is_delete = 0 </update> <!-- 刪除 --> <update id="delete" parameterType="String"> update map set is_delete = 1 where id = #{id} </update> <!-- id查詢 --> <select id="find" resultMap="BaseResultMap"> select * from map where id = #{id} and is_delete = 0 </select> <!-- 列表查詢總數 --> <select id="count" resultType="int"> select count(1) from map <where> is_delete = 0 <if test="name != null and name != ''"> and name like concat('%', #{name}, '%') </if> </where> </select> <!-- 列表查詢 --> <select id="list" resultMap="BaseResultMap"> select * from map <where> is_delete = 0 <if test="name != null and name != ''"> and name like concat('%', #{name}, '%') </if> </where> <if test="pageParam != null"> limit ${(pageParam.pageIndex - 1) * pageParam.pageSize}, ${pageParam.pageSize} </if> </select> </mapper>
最後,我們新建com.idlewow.map.manager包,新建一個類WowMapManager,此類通過呼叫mapper來實現具體業務:
package com.idlewow.map.manager; import com.idlewow.common.model.PageList; import com.idlewow.map.mapper.WowMapMapper; import com.idlewow.map.model.WowMap; import com.idlewow.query.model.WowMapQueryParam; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.List; @Component public class WowMapManager { @Autowired WowMapMapper wowMapMapper; public void insert(WowMap wowMap) { int effected = wowMapMapper.insert(wowMap); if (effected == 0) { throw new RuntimeException("sql effected 0 rows"); } } public void batchInsert(List<WowMap> list) { int splitSize = 100; int index = 0; int total = list.size(); while (index <= total) { int end = index + splitSize; if (end > total) { end = total; } List<WowMap> sublist = list.subList(index, end); int effected = wowMapMapper.batchInsert(sublist); if (effected == 0) { throw new RuntimeException("sql effected 0 rows"); } index += splitSize; } } public void update(WowMap t) { int effected = wowMapMapper.update(t); if (effected == 0) { throw new RuntimeException("sql effected 0 rows"); } } public void delete(String id) { int effected = wowMapMapper.delete(id); if (effected == 0) { throw new RuntimeException("sql effected 0 rows"); } } public WowMap find(String id) { WowMap wowMap = wowMapMapper.find(id); return wowMap; } public PageList<WowMap> list(WowMapQueryParam queryParam) { PageList<WowMap> pageList = new PageList<WowMap>(); int count = wowMapMapper.count(queryParam); List<WowMap> list = wowMapMapper.list(queryParam); pageList.setTotalCount(count); pageList.setData(list); pageList.setPageParam(queryParam.getPageParam()); return pageList; } }
另外,@Componet註解需要依賴spring-context包。還有我們寫SQL的xml檔案是資原始檔,但為了方便檢視編輯,我們直接把它放在了程式碼目錄下,所以編譯的時候不會被打包,需要在pom中新增配置如下:
</dependencies> ........ ........ <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.6.RELEASE</version> </dependency> </dependencies> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> <filtering>false</filtering> </resource> </resources> </build>
這樣,我們的資料訪問層邏輯就全部實現了。通過在RMS模組的controller中注入manager,即可實現對底層資料的訪問。
二、controller層的實現
在com.idlewow.rms.controller包中,新建類MapController,在Contoller中,我們初步實現了對資料的增刪查改。注意,這裡list()方法,返回的字串“/manage/map/list",代表檢視所在路徑,根據spring-mvc.xml中配置的檢視路由解析規則,即返回/WEB-INF/views/manage/map/list.jsp頁面。但如果在該方法上加上註解@ResponseBody,則代表直接返回該字串,不會去尋找檢視。在post方法中,我們就是直接返回資料的json串。程式碼如下:
package com.idlewow.rms.controller; import com.idlewow.common.model.CommonResult; import com.idlewow.common.model.PageList; import com.idlewow.map.manager.WowMapManager; import com.idlewow.map.model.WowMap; import com.idlewow.query.model.WowMapQueryParam; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequestMapping("/manage/map") public class MapController extends BaseController { @Autowired WowMapManager wowMapManager; @RequestMapping("/list") public Object list() { return "/manage/map/list"; } @ResponseBody @RequestMapping(value = "/list", method = RequestMethod.POST) public Object list(@RequestParam(value = "page", defaultValue = "1") int pageIndex, @RequestParam(value = "limit", defaultValue = "10") int pageSize, WowMapQueryParam queryParam) { queryParam.setPage(pageIndex, pageSize); PageList<WowMap> pageList = wowMapManager.list(queryParam); return this.parseTable(pageList); } @RequestMapping("/add") public Object add() { return "/manage/map/add"; } @ResponseBody @RequestMapping(value = "/add", method = RequestMethod.POST) public Object add(@RequestBody WowMap wowMap) { try { wowMap.setCreateUser(this.currentUserName()); wowMapManager.insert(wowMap); return CommonResult.success(); } catch (Exception ex) { return CommonResult.fail(); } } @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET) public Object edit(@PathVariable String id, Model model) { WowMap wowMap = wowMapManager.find(id); model.addAttribute(wowMap); return "/manage/map/edit"; } @ResponseBody @RequestMapping(value = "/edit/{id}", method = RequestMethod.POST) public Object edit(@PathVariable String id, @RequestBody WowMap wowMap) { try { if (!id.equals(wowMap.getId())) { return CommonResult.fail("id不一致"); } wowMap.setUpdateUser(this.currentUserName()); wowMapManager.update(wowMap); return CommonResult.success(); } catch (Exception ex) { return CommonResult.fail(); } } @ResponseBody @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST) public Object delete(@PathVariable String id) { try { wowMapManager.delete(id); return CommonResult.success(); } catch (Exception ex) { return CommonResult.fail(); } } }
其中, CommonResult類是我定義的一個通用的結果返回類,PageList和PageParam是分頁相關的輔助類,WowMapQueryParam是列表查詢的引數類。
另外,前端列表展示使用了layui的datatable,需要給他返回對應的資料結構。因此,我們定義一個抽象類BaseController,實現對列表資料結構的轉換,同時提供查詢當前登入使用者的方法。其他的Controller如無特殊情況均繼承BaseController,程式碼如下:
package com.idlewow.rms.vo; import lombok.Data; import java.io.Serializable; import java.util.List; @Data public class LayuiDataTable<T> implements Serializable { private Integer code; private String message; private Integer count; private List<T> data; }
package com.idlewow.rms.controller; import com.idlewow.admin.model.SysAdmin; import com.idlewow.common.model.PageList; import com.idlewow.rms.vo.LayuiDataTable; import org.springframework.beans.factory.annotation.Autowired; import javax.servlet.http.HttpSession; public abstract class BaseController { private static final String LoginUserKey = "loginuser"; @Autowired protected HttpSession httpSession; protected SysAdmin currentUser() { return (SysAdmin) httpSession.getAttribute(LoginUserKey); } protected String currentUserName() { return this.currentUser().getUsername(); } protected LayuiDataTable parseTable(PageList pageList) { LayuiDataTable dataTable = new LayuiDataTable(); dataTable.setMessage("讀取成功"); dataTable.setCode(0); dataTable.setCount(pageList.getTotalCount()); dataTable.setData(pageList.getData()); return dataTable; } }
寫完控制器,前端頁面,我們直接套用x-admin的模板。在/WEB-INF/views/manage/map目錄下,建立頁面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ include file="/authorize.jsp" %> <!DOCTYPE html> <html class="x-admin-sm"> <head> <meta charset="UTF-8"> <title>地圖管理</title> <meta name="renderer" content="webkit"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi"/> <link rel="stylesheet" href="<%=path%>/css/font.css"> <link rel="stylesheet" href="<%=path%>/css/xadmin.css"> <script type="text/javascript" src="<%=path%>/lib/layui/layui.js" charset="utf-8"></script> <script type="text/javascript" src="<%=path%>/js/xadmin.js"></script> </head> <body> <div class="x-nav"> <span class="layui-breadcrumb"> <a href="">首頁</a> <a href="">後臺管理</a> <a> <cite>地圖</cite></a> </span> <a class="layui-btn layui-btn-small" style="line-height:1.6em;margin-top:3px;float:right" onclick="location.reload()" title="重新整理"> <i class="layui-icon layui-icon-refresh" style="line-height:30px"></i></a> </div> <div class="layui-fluid"> <div class="layui-row layui-col-space15"> <div class="layui-col-md12"> <div class="layui-card"> <div class="layui-card-body "> <form id="queryForm" class="layui-form layui-col-space5" method="post"> <div class="layui-inline layui-show-xs-block"> <input type="text" name="name" placeholder="請輸入地圖名稱" autocomplete="off" class="layui-input"> </div> <div class="layui-inline layui-show-xs-block"> <button class="layui-btn" lay-submit lay-filter="search" type="button" onclick="search();"> <i class="layui-icon"></i>查詢 </button> </div> <div class="layui-inline layui-show-xs-block"> <button class="layui-btn" type="button" onclick="reset();"> 重置</button> </div> <div class="layui-inline layui-show-xs-block"> <button type="button" class="layui-btn" onclick="xadmin.open('新增地圖','add',500,500)"> <i class="layui-icon"></i>新增地圖 </button> </div> <div class="layui-upload layui-inline layui-show-xs-block"> <button type="button" class="layui-btn layui-btn-normal" id="btnSelectFile">選擇Excel</button> <button type="button" class="layui-btn" id="btnImport">開始匯入</button> </div> </form> </div> <div class="layui-card-body "> <table class="layui-table layui-form" id="datatable"></table> </div> </div> </div> </div> </div> </body> <script type="text/javascript" src="<%=path%>/js/helper.js?v=0530"></script> <script type="text/javascript" src="<%=path%>/js/wow/manage/map/list.js?v=0530"></script> </html>
<%@ page import="com.idlewow.rms.util.DropDownUtil" %> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ include file="/authorize.jsp" %> <!DOCTYPE html> <html class="x-admin-sm"> <head> <meta charset="UTF-8"> <title>編輯地圖</title> <meta name="renderer" content="webkit"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi"/> <link rel="stylesheet" href="<%=path%>/css/font.css"> <link rel="stylesheet" href="<%=path%>/css/xadmin.css"> <script type="text/javascript" src="<%=path%>/lib/layui/layui.js" charset="utf-8"></script> <script type="text/javascript" src="<%=path%>/js/xadmin.js"></script> </head> <body> <div class="layui-fluid"> <div class="layui-row"> <form:form class="layui-form" method="post" modelAttribute="wowMap"> <form:hidden path="id"/> <div class="layui-form-item"> <form:label path="name" class="layui-form-label"> <span class="x-red">*</span>地圖名稱 </form:label> <div class="layui-input-inline"> <form:input path="name" lay-verify="required" autocomplete="off" class="layui-input"/> </div> </div> <div class="layui-form-item"> <form:label path="occupy" class="layui-form-label"> <span class="x-red">*</span>領土歸屬 </form:label> <div class="layui-input-inline"> <form:select path="occupy" items="<%= DropDownUtil.OccupyMap %>"></form:select> </div> </div> <div class="layui-form-item"> <form:label path="description" class="layui-form-label"> 地圖描述 </form:label> <div class="layui-input-inline"> <form:textarea path="description" class="layui-textarea"></form:textarea> </div> </div> <div class="layui-form-item"> <label class="layui-form-label"></label> <div class="layui-input-inline"> <button class="layui-btn" lay-filter="edit" lay-submit type="button">修改</button> </div> </div> </form:form> </div> </div> <script type="text/javascript" src="<%=path%>/js/helper.js?v=0531"></script> <script type="text/javascript" src="<%=path%>/js/wow/manage/map/edit.js?v=0510"></script> </body> </html>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page import="com.idlewow.rms.util.DropDownUtil" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ include file="/authorize.jsp" %> <!DOCTYPE html> <html class="x-admin-sm"> <head> <meta charset="UTF-8"> <title>新增地圖</title> <meta name="renderer" content="webkit"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi"/> <link rel="stylesheet" href="<%=path%>/css/font.css"> <link rel="stylesheet" href="<%=path%>/css/xadmin.css"> <script type="text/javascript" src="<%=path%>/lib/layui/layui.js" charset="utf-8"></script> <script type="text/javascript" src="<%=path%>/js/xadmin.js"></script> </head> <body> <div class="layui-fluid"> <div class="layui-row"> <form class="layui-form" method="post"> <div class="layui-form-item"> <label for="name" class="layui-form-label"> <span class="x-red">*</span>地圖名稱 </label> <div class="layui-input-inline"> <input type="text" id="name" name="name" required lay-verify="required" autocomplete="off" class="layui-input"> </div> </div> <div class="layui-form-item"> <label for="occupy" class="layui-form-label"> <span class="x-red">*</span>領土歸屬 </label> <div class="layui-input-inline"> <% request.setAttribute("occupyMap", DropDownUtil.OccupyMap); %> <select name="occupy" id="occupy"> <option value="">請選擇領土歸屬</option> <c:forEach items="${occupyMap}" var="item"> <option value="${item.key}">${item.value}</option> </c:forEach> </select> </div> </div> <div class="layui-form-item"> <label for="description" class="layui-form-label"> 地圖描述 </label> <div class="layui-input-inline"> <textarea name="description" id="description" class="layui-textarea"></textarea> </div> </div> <div class="layui-form-item"> <label class="layui-form-label"></label> <div class="layui-input-inline"> <button class="layui-btn" lay-filter="add" lay-submit type="button">新增</button> </div> </div> </form> </div> </div> <script type="text/javascript" src="<%=path%>/js/helper.js?v=0531"></script> <script type="text/javascript" src="<%=path%>/js/wow/manage/map/add.js?v=0531"></script> </body> </html>
在/js/wow/manage/map目錄下,建立相應的js指令碼:
layui.use(['upload', 'table', 'form'], function () { var table = layui.table; table.render({ elem: '#datatable' , url: '/manage/map/list' , method: 'post' , cellMinWidth: 80 , cols: [[ {field: 'id', width: 50, title: 'id'} , {field: 'name', title: '地圖名稱'} , { field: 'occupy', title: '領土歸屬', templet: function (d) { return enumUtil.occupyImage(d.occupy) + enumUtil.occupy(d.occupy); } } , { title: '操作', templet: function (d) { return '<button class="layui-btn layui-btn-xs" onclick="xadmin.open(\'編輯地圖\',\'edit/' + d.id + '\', 500, 500)" type="button"><i class="layui-icon"></i>編輯</button>' + '<button class="layui-btn-danger layui-btn layui-btn-xs" onclick="remove(this, \'' + d.id + '\')" type="button"><i class="layui-icon"></i>刪除</button>'; } } ]] , page: { layout: ['limit', 'count', 'prev', 'page', 'next', 'skip'] //自定義分頁佈局 , limits: [10, 20, 30, 40, 50] , groups: 3 //只顯示 1 個連續頁碼 , first: '首頁' , last: '尾頁' } }); }); function search() { var table = layui.table; table.reload('datatable', { where: { name: $('input[name="name"]').val() }, page: { curr: 1 } }); } function reset(){ $('#queryForm').reset(); } function remove(obj, id) { layer.confirm('確認要刪除嗎?', function () { $.ajax({ url: '/manage/map/delete/' + id, type: 'post', success: function (result) { if (result.code === 1) { $(obj).parents("tr").remove(); layer.msg('刪除成功', {icon: 1, time: 1000}); } else { layer.alert("刪除失敗", {icon: 5}); } }, error: function () { layer.alert("請求失敗", {icon: 5}); } }); }); }
layui.use(['form', 'layer'], function () { var form = layui.form; form.render(); form.verify({}); form.on('submit(edit)', function (data) { $.ajax({ url: '/manage/map/edit/' + data.field.id, type: 'post', contentType: "application/json; charset=utf-8", data: JSON.stringify(data.field), success: function (result) { if (result.code === 1) { layer.alert(result.message, {icon: 6}, function () { xadmin.close(); xadmin.father_reload(); }); } else { layer.alert(result.message, {icon: 5}); } }, error: function () { layer.alert("請求失敗", {icon: 5}); } }); }); });
layui.use(['form', 'layer'], function () { var form = layui.form; form.verify({}); form.on('submit(add)', function (data) { $.ajax({ url: '/manage/map/add', type: 'post', contentType: "application/json; charset=utf-8", data: JSON.stringify(data.field), success: function (result) { if (result.code === 1) { layer.alert(result.message, {icon: 6}, function () { xadmin.close(); xadmin.father_reload(); }); } else { layer.alert(result.message, {icon: 5}); } }, error: function () { layer.alert("請求失敗", {icon: 5}); } }); }); });
三、專案啟動
本次,我們修改了facade和core專案,這兩個專案是作為jar包被rms模組引用的,因此必須先將其編譯打包,這裡我們用第(二)章定義的打包命令直接將整個專案重新打包。以後凡是jar包專案有改動,我們啟動web專案前,都先重新打包一遍。
另外,maven的編譯外掛可能預設的jdk版本是1.5,我們在pom中配置一下,配成1.8,配置如下:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> ………… ………… </plugins> </build>
OK,全部搞定之後,我們執行一下,看下效果:
小結
本章,我們初步實現了後臺管理系統資料配置的增刪查改,但還有很多功能不完善。
比如,新增、編輯時的資料沒有進行校驗;單個錄入資料太麻煩,想要通過excel批量錄入;出現異常時缺乏相應的日誌記錄,等等。
這些內容,我們都將在後面的章節中持續完善。
本章原始碼下載地址:https://idlestudio.ctfile.com/fs/14960372-383560985
歡迎1元催更