一、效果展示
列表显示的效果如下图:
列表引用了GridManager框架,可快速、灵活的对table标签进行实例化. 使用简单快捷, 功能强大纯原生javascript实现,不依赖任何框架使用简单快捷,功能强大与用户进行沟通,采纳来自于使用的需求,并不间段的进行升级维护。
二、gridManager的使用步骤
首先,我们在页面上加入相应的css与js(链接:https://pan.baidu.com/s/1vK3me0atVwYhsTB3UNX3AA 提取码:m40n)
相关jar包:(链接:https://pan.baidu.com/s/1Nk5pXvHDHKeyk2y5Iic0Lg 提取码:gnwh)
<link rel="stylesheet" type="text/css" href="/js/jquery/plugin/GridManager/css/gm.css"/>
<script type="text/javascript" src="/js/jquery/plugin/GridManager/js/gm.js"></script>
然后在html页面加上相应的table。
<table id=‘table-demo-baseCode‘ ></table>
再在 js中配置查询,这里gridManager发送的是一个ajax异步请求,匹配ArticleController.java的"/system/article/datagrid"请求。
1 <script type="text/javascript"> 2 document.querySelector(‘#table-demo-baseCode‘).GM({ 3 gridManagerName: ‘demo-baseCode‘,//指定表格实例的唯一标识 4 ajaxData: ‘/system/article/datagrid‘, //前台发送ajax的请求 5 supportAjaxPage: true, //启用分页 6 sizeData: [5,10,15,20], //配置每页显示条数的下拉项,数组元素仅允许为正整数 7 pageSize: 5, //配置初次进入时每页的显示条数,需要与sizeData中的值匹配 8 currentPageKey: "localPage", //请求参数中当前页key键值,默认为cPage 9 pageSizeKey: "pageSize", //请求参数中每页显示条数key健值, 默认为pSize 10 ajaxType: ‘POST‘, //请求方式 11 height:‘100%‘, //显示尺寸100% 12 columnData: [ 13 { 14 key: ‘title‘, //json格式的数据的key值 15 text: ‘文章标题‘, //表头文本 16 align:‘center‘ 17 },{ 18 key: ‘type‘, 19 text: ‘文章类型‘, 20 align:‘center‘, 21 template:function(cell, row, index, key){ 22 //获取到ArticleServiceImpl中设置的文章类型(注意:这里设置的是t_article_type表里所有的字段,cell接收的是t_article和t_article_type中所有字段) 23 return cell.name; 24 } 25 },{ 26 key: ‘clickCount‘, 27 text: ‘点击次数‘, 28 align:‘center‘ 29 },{ 30 key: ‘createDate‘, 31 text: ‘创建时间‘, 32 align:‘center‘ 33 },{ 34 key: ‘enable‘, 35 text: ‘是否启用‘, 36 align:‘center‘, 37 //cell:当前字段的值 row:当前行的数据,当前对象 index:当前对象的下标 key:enable 38 template:function(cell, row, index, key){ 39 return cell ? "<span style=‘color:green‘>启用</span>":"<span style=‘color:red‘>禁用</span>"; 40 } 41 },{ 42 key: ‘id‘, 43 text: ‘操作 <a href="javascript:void(0);" class="addButton" style="color:olive">添加</a>‘, 44 align: ‘center‘, 45 //cell:当前字段的值 row:当前行的数据,当前对象 index:当前对象的下标 key:enable 46 template: function(cell, row, index, key){ 47 return "<a href=‘javascript:void(0);‘ style=‘color:olive‘ data-id=‘"+cell+"‘>删除</a> <a href=‘javascript:void(0);‘ data-row=‘"+JSON.stringify(row)+"‘ style=‘color:blue‘>修改</a>"; 48 } 49 } 50 ] 51 });
三、编写控制层Controller和业务层Service代码
控制器层ArticleController.java的"/system/article/datagrid"请求处理,如下:
1 /** 2 * @Title: ArticleController.java 3 * @Package:cn.itsource.cms.controller 4 * @Description:(文章Article模块) 5 * @author:Joi 6 * @date:2020年6月5日 7 * @version:V1.0 8 */ 9 //Controller就是单例的(使用成员变量请注意线程安全问题) 10 //注:不要忘了,配置全注解扫描包才能认识@Controller 11 @Controller 12 @RequestMapping("/system/article")//配置访问路径 13 public class ArticleController { 14 @Autowired 15 private IArticleService service; 16 17 /** 18 * @Description:(匹配请求/system/article/datagrid 调用service代码,传递查询条件) 19 * @param:@param query 20 * @param:@return 21 * @return:PageBean<Article> 22 * @author:Joi 23 * @date:2020年6月5日 24 * @version:V1.0 25 */ 26 @RequestMapping("/datagrid") 27 @ResponseBody//跨过视图解析器,返回json格式对象 28 public PageBean<Article> datagrid(ArticleQuery query) { 29 //调用service代码,传递查询条件 30 return service.findPageList(query); 31 } 32 }
IArticleService接口中有:PageBean<Article> findPageList(ArticleQuery query);方法,用于ArticleServiceImpl实现,实现代码如下:
1 @Service//实例化bean的注解 2 public class ArticleServiceImpl implements IArticleService{ 3 @Autowired//ArticleMapper 注入 4 private ArticleMapper mapper; 5 @Autowired//ArticleTypeMapper 注入 6 private ArticleTypeMapper typeMapper; 7 8 /** 9 * 查询指定页面中的内容返回一个list对象,前台传入一个ArticleQuery对象(包含localPage和pageSize), 10 * 然后返回一个满足gridManager规范的PageBean对象,用于前台接收数据 11 */ 12 @Override 13 public PageBean<Article> findPageList(ArticleQuery query) { 14 //System.out.println(query); 15 //1、先查询数量(修改ArticleMapper接口中的查询为查询总数量的高级查询) 16 Long totals = mapper.findPageCountByQuery(query); 17 if (totals == 0l) {//根据查询条件没匹配到对象,返回一个空的默认PageBean 18 return new PageBean<Article>(); 19 } 20 //查询指定页面中的内容返回一个list对象 21 //修改ArticleMapper.xml的findPageList方法为高级分页查询 22 List<Article> articles = mapper.findPageList(query); 23 for (Article article : articles) { 24 //查询文章id 25 Long id = article.getTypeId(); 26 //设置的是整个ArticleType对象,里面包含id name code等内容 27 ArticleType type = typeMapper.findOne(id); 28 //设置文章类型 29 article.setType(type); 30 } 31 return new PageBean<Article>(totals,articles); 32 } 33 34 }
其中PageBean为封装的一个传给前台接收的类,该类封装的gridManager接受的规范格式(totals:数据总长度 和 data:查询到的数据集合),具体代码如下:
1 /** 2 * @Title: PageBean.java 3 * @Package:cn.itsource.cms.util 4 * @Description:(封装返回给gridmanager接收的data 数据列表和totals 数据长度) 5 * @author:Joi 6 * @date:2020年6月5日 7 * @version:V1.0 8 */ 9 public class PageBean<T> { 10 //传递数据总长度 11 private Long totals = 0l; 12 //传递的list对象 13 private List<T> data = new ArrayList<>(); 14 //无参构造 15 public PageBean() { 16 } 17 //有参构造 18 public PageBean(Long totals, List<T> data) { 19 this.totals = totals; 20 this.data = data; 21 } 22 public Long getTotals() { 23 return totals; 24 } 25 public void setTotals(Long totals) { 26 this.totals = totals; 27 } 28 public List<T> getData() { 29 return data; 30 } 31 public void setData(List<T> data) { 32 this.data = data; 33 } 34 @Override 35 public String toString() { 36 return "PageBean [totals=" + totals + ", data=" + data + "]"; 37 } 38 }
四、spring框架注入mapper
ArticleMapper接口中 Long findPageCountByQuery(ArticleQuery query); 方法实现分页查询,这里用到Spring框架,将Mapper接口交给spring去管理
1 <!-- 将Mapper接口交给Spring去管理 --> 2 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 3 <!-- 指定mapper接口的包路径 --> 4 <property name="basePackage" value="cn.itsource.cms.mapper"></property> 5 </bean>
在ArticleMapper.xml中写sql语句,自动绑定ArticleMapper.java接口中的findPageCountByQuery方法名。
1 1 <?xml version="1.0" encoding="UTF-8" ?> 2 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 3 3 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 4 4 5 5 <mapper namespace="cn.itsource.cms.mapper.ArticleMapper"> 6 6 <!-- 分页查询文章 --> 7 7 <select id="findPageList" resultType="Article" parameterType="ArticleQuery"> 8 8 select * from t_article 9 9 <include refid="query"></include> 10 10 limit #{begin},#{pageSize} 11 11 </select> 12 12 13 13 <!-- Long findPageCountByQuery(ArticleQuery query); --> 14 14 <select id="findPageCountByQuery" resultType="long"> 15 15 select count(*) from t_article 16 16 <include refid="query"></include> 17 17 </select> 18 18 <!-- 抽取sql --> 19 19 <sql id="query"> 20 20 <where> 21 21 <if test=‘title != null and !"".equals(title.trim())‘> 22 22 and title like concat(‘%‘,trim(#{title}),‘%‘) 23 23 </if> 24 24 <if test="typeId != null"> 25 25 and typeId = #{typeId} 26 26 </if> 27 27 <if test="enable != null"> 28 28 and enable = #{enable} 29 29 </if> 30 30 </where> 31 31 </sql> 32 32 </mapper>
五、完成article.jsp页面
1 <%@ page pageEncoding="UTF-8"%> 2 <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 3 <!DOCTYPE html> 4 <html> 5 <head> 6 <title>CMS系统欢迎您</title> 7 <meta charset="utf-8"> 8 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 9 <meta name="viewport" content="width=device-width, initial-scale=1"> 10 <!-- Main CSS--> 11 <link rel="stylesheet" type="text/css" href="/static/system/css/main.css"> 12 <!-- Font-icon css--> 13 <link rel="stylesheet" type="text/css" href="/static/system/css/font-awesome.min.css"> 14 <!-- 引入girdmanager的css --> 15 <link rel="stylesheet" href="/static/system/gridmanager/css/gm.css"> 16 <!-- 引入gridmanager的js --> 17 <script type="text/javascript" src="/static/system/gridmanager/js/gm.js"></script> 18 </head> 19 <body class="app sidebar-mini"> 20 <!-- 导航条--> 21 <header class="app-header"><a class="app-header__logo" href="index.html">源码时代</a> 22 <a class="app-sidebar__toggle" href="#" data-toggle="sidebar" aria-label="Hide Sidebar"></a> 23 <!-- 导航条右边菜单--> 24 <ul class="app-nav"> 25 <!-- 用户菜单--> 26 <li class="dropdown"> 27 <a class="app-nav__item" href="#" data-toggle="dropdown" aria-label="Open Profile Menu"> 28 <i class="fa fa-user fa-lg"></i></a> 29 <ul class="dropdown-menu settings-menu dropdown-menu-right"> 30 <li><a class="dropdown-item" href="page-login.html"> 31 <i class="fa fa-sign-out fa-lg"></i> 退出</a></li> 32 </ul> 33 </li> 34 </ul> 35 </header> 36 <!-- Sidebar menu--> 37 <div class="app-sidebar__overlay" data-toggle="sidebar"></div> 38 39 <!-- 侧边栏 --> 40 <aside class="app-sidebar"> 41 <div class="app-sidebar__user"> 42 <img class="app-sidebar__user-avatar" width="48px" height="48px" src="/static/system/images/m1.jpg" alt="User Image"> 43 <div > 44 <p class="app-sidebar__user-name">江小江</p> 45 </div> 46 </div> 47 <ul class="app-menu"> 48 <li> 49 <a class="app-menu__item active" href="/system/article/index"> 50 <i class="app-menu__icon fa fa-dashboard"></i> 51 <span class="app-menu__label">文章管理</span> 52 </a> 53 </li> 54 </ul> 55 </aside> 56 57 <!-- 中间显示内容的 --> 58 <main class="app-content"> 59 60 <!-- 删除时的确认模态框 --> 61 <div class="modal fade" id="delModel"> 62 <div class="modal-dialog"> 63 <div class="modal-content message_align"> 64 <div class="modal-header"> 65 <button type="button" class="close" data-dismiss="modal" aria-label="Close"> 66 <span aria-hidden="true">×</span> 67 </button> 68 </div> 69 <div class="modal-body"> 70 <h6 style="color: orange">您确认要删除吗?</h6> 71 </div> 72 <div class="modal-footer"> 73 <button type="button" class="btn btn-default" data-dismiss="modal" >取消</button> 74 <a href="javascript:void(0);" id="delModelButton" class="btn" >确定</a> 75 </div> 76 </div><!-- /.modal-content --> 77 </div><!-- /.modal-dialog --> 78 </div> 79 80 <!-- 添加或者修改的模态框 --> 81 <div class="modal fade" id="saveModel"> 82 <div class="modal-dialog"> 83 <div class="modal-content message_align"> 84 <div class="modal-header"> 85 <button type="button" class="close" data-dismiss="modal" aria-label="Close"> 86 <span aria-hidden="true">×</span> 87 </button> 88 </div> 89 <div class="modal-body"> 90 <form action="/system/article/save" method="post" class="form-horizontal" id="saveForm"> 91 <input type="hidden" name="id"> 92 <div class="form-group row"> 93 <label for="title" class="control-label col-md-3">文章标题</label> 94 <div class="col-md-9"> 95 <input class="form-control" type="text" name="title"> 96 </div> 97 </div> 98 <div class="form-group row"> 99 <label for="typeId" class="control-label col-md-3">文章类型</label> 100 <div class="col-md-9"> 101 <select name="typeId" class="form-control"> 102 <c:forEach items="${types}" var="t"> 103 <option value="${t.id}">${t.name}</option> 104 </c:forEach> 105 </select> 106 </div> 107 </div> 108 <div class="form-group row"> 109 <label for="enable" class="control-label col-md-3" >是否启用</label> 110 <div class="col-md-9"> 111 <div class="form-check"> 112 <label class="form-check-label"> 113 <input class="form-check-input" type="radio" checked="checked" id="enable" name="enable" value="1">启用 114 </label> 115 </div> 116 <div class="form-check"> 117 <label class="form-check-label"> 118 <input class="form-check-input" type="radio" name="enable" value="0">禁用 119 </label> 120 </div> 121 </div> 122 </div> 123 <div class="form-group row"> 124 <label for="content" class="control-label col-md-3">文章内容</label> 125 <div class="col-md-9"> 126 <textarea class="form-control" style="resize: none" rows="4" name="content"></textarea> 127 </div> 128 </div> 129 </form> 130 </div> 131 <div class="modal-footer"> 132 <button type="button" class="btn btn-default" data-dismiss="modal">取消</button> 133 <a href=‘javascript:void(0);‘ id="saveButton" class="btn btn-success" >确定</a> 134 </div> 135 </div> 136 </div> 137 </div> 138 139 <!-- 高级查询 --> 140 <div class="row app-title"> 141 <div class="col-md-12"> 142 <!-- 表单 --> 143 <form id="queryForm" class="form-inline"> 144 <div class="form-group"> 145 <label for="title">标题:</label> 146 <input type="text" class="form-control" name="title" id="title"> 147 </div> 148 <div class="form-group" style="margin-left: 20px"> 149 <label>文章类型:</label> 150 <select name="typeId" class="form-control" id="typeId"> 151 <option value="">请选择</option> 152 <c:forEach items="${types }" var="t"> 153 <option value="${t.id}">${t.name }</option> 154 </c:forEach> 155 </select> 156 </div> 157 <div class="form-group" style="margin-left: 20px"> 158 <label>是否启用:</label> 159 <select name="enable" class="form-control" id="enable"> 160 <option value="">请选择</option> 161 <option value="1">启用</option> 162 <option value="0">禁用</option> 163 </select> 164 </div> 165 <button type="button" id="queryButton" class="btn btn-success" style="margin-left: 20px">查询</button> 166 </form> 167 </div> 168 </div> 169 170 <!-- 列表展示 --> 171 <div class="row app-title"> 172 <div class="col-md-12"> 173 <!-- 存放table列表 --> 174 <table id=‘table-demo-baseCode‘ ></table> 175 </div> 176 </div> 177 </main> 178 <!-- Essential javascripts for application to work--> 179 <script src="/static/system/js/jquery-3.3.1.min.js"></script> 180 <script type="text/javascript" src="/static/system/js/jquery.jdirk.js"></script> 181 <script type="text/javascript" src="/static/system/js/jquery-form.js"></script> 182 <script type="text/javascript" src="/static/system/js/form-load.js"></script> 183 <script src="/static/system/js/popper.min.js"></script> 184 <script src="/static/system/js/bootstrap.min.js"></script> 185 <script src="/static/system/js/main.js"></script> 186 <!-- The javascript plugin to display page loading on top--> 187 <script src="/static/system/js/plugins/pace.min.js"></script> 188 <script type="text/javascript"> 189 document.querySelector(‘#table-demo-baseCode‘).GM({ 190 gridManagerName: ‘demo-baseCode‘,//指定表格实例的唯一标识 191 ajaxData: ‘/system/article/datagrid‘, //前台发送ajax的请求 192 supportAjaxPage: true, //启用分页 193 sizeData: [5,10,15,20], //配置每页显示条数的下拉项,数组元素仅允许为正整数 194 pageSize: 5, //配置初次进入时每页的显示条数,需要与sizeData中的值匹配 195 currentPageKey: "localPage", //请求参数中当前页key键值,默认为cPage 196 pageSizeKey: "pageSize", //请求参数中每页显示条数key健值, 默认为pSize 197 ajaxType: ‘POST‘, //请求方式 198 height:‘100%‘, //显示尺寸100% 199 columnData: [ 200 { 201 key: ‘title‘, //json格式的数据的key值 202 text: ‘文章标题‘, //表头文本 203 align:‘center‘ 204 },{ 205 key: ‘type‘, 206 text: ‘文章类型‘, 207 align:‘center‘, 208 template:function(cell, row, index, key){ 209 //获取到ArticleServiceImpl中设置的文章类型(注意:这里设置的是t_article_type表里所有的字段,cell接收的是t_article和t_article_type中所有字段) 210 return cell.name; 211 } 212 },{ 213 key: ‘clickCount‘, 214 text: ‘点击次数‘, 215 align:‘center‘ 216 },{ 217 key: ‘createDate‘, 218 text: ‘创建时间‘, 219 align:‘center‘ 220 },{ 221 key: ‘enable‘, 222 text: ‘是否启用‘, 223 align:‘center‘, 224 //cell:当前字段的值 row:当前行的数据,当前对象 index:当前对象的下标 key:enable 225 template:function(cell, row, index, key){ 226 return cell ? "<span style=‘color:green‘>启用</span>":"<span style=‘color:red‘>禁用</span>"; 227 } 228 },{ 229 key: ‘id‘, 230 text: ‘操作 <a href="javascript:void(0);" class="addButton" style="color:olive">添加</a>‘, 231 align: ‘center‘, 232 //cell:当前字段的值 row:当前行的数据,当前对象 index:当前对象的下标 key:enable 233 template: function(cell, row, index, key){ 234 return "<a href=‘javascript:void(0);‘ style=‘color:olive‘ data-id=‘"+cell+"‘>删除</a> <a href=‘javascript:void(0);‘ data-row=‘"+JSON.stringify(row)+"‘ style=‘color:blue‘>修改</a>"; 235 } 236 } 237 ] 238 }); 239 240 //注册查询点击事件 241 $(function(){ 242 $("#queryButton").on("click",function(){ 243 //这个方法是GridManager提供的一个提交数据到后台的方法 244 //第一个参数:GridManager的名称 245 //第二个参数:提交的数据 246 //请求:/system/article/datagrid 247 //var titile = $("#title").val()手动获取方式 248 var jsonForm = $("#queryForm").serializeObject(); 249 console.debug(jsonForm); 250 GridManager.setQuery(‘demo-baseCode‘, jsonForm); 251 }); 252 253 254 /* 删除数据的异步请求:给所有的删除按钮注册单击事件 */ 255 //事件委托 256 $("#table-demo-baseCode").on("click","a[data-id]",function(){ 257 //获取id 258 var id = $(this).data("id"); 259 //显示删除模态框 260 $("#delModel").modal("show"); 261 //先注销确认按钮的所有事件:避免点击删除按钮给确认按钮绑定多个事件 262 $("#delModelButton").off(); 263 //确认的点击事件 264 $("#delModelButton").on("click",function(){ 265 //get请求 266 $.get("/system/article/del",{"id":id},function(data){ 267 if(data.success){ 268 $("#delModel").modal("hide"); 269 //刷新表格 270 GridManager.refreshGrid(‘demo-baseCode‘); 271 }else{ 272 alert(data.msg); 273 } 274 },"json");//get请求 275 });//"#delModelButton点击事件 276 });//#table-demo-baseCode 277 278 /* 新增功能:点击新增按钮绑定事件 */ 279 $("#table-demo-baseCode").on("click",".addButton",function(){ 280 //清空表单数据 281 $("#saveForm").clearForm(); 282 //手动清空隐藏域id 283 $("#saveForm input[name=‘id‘]").val(""); 284 //手动设置启用状态:clearForm()会将启用状态也清空 285 $("#enable").prop("checked",true); 286 //显示模态框 287 $("#saveModel").modal("show"); 288 }); 289 290 //点击更新按钮 事件委托 291 $("#table-demo-baseCode").on("click","a[data-row]",function(){ 292 var row = $(this).data("row"); 293 //清空表单数据 294 $("#saveForm").clearForm(); 295 //手动清空隐藏域id 296 $("#saveForm input[name=‘id‘]").val(""); 297 //手动设置启用状态:clearForm()会将启用状态也清空 298 $("#saveModel #enable").prop("checked",true); 299 //回显数据 300 $("#saveForm").setForm(row); 301 //显示模态框 302 $("#saveModel").modal("show"); 303 //console.debug(obj); 304 }); 305 306 /*点击添加和修改模态框的确认按钮时的业务逻辑*/ 307 $("#saveButton").on("click",function(){ 308 //将表单以ajax异步请求的方式提交到后台,请求为:/system/article/save 309 $("#saveForm").ajaxSubmit({//ajax提交请求 310 success:function(result){ 311 if(result.success){ 312 //关闭模态框 313 $("#saveModel").modal("hide"); 314 //刷新表格 315 GridManager.refreshGrid(‘demo-baseCode‘); 316 }else{ 317 alert(result.msg); 318 } 319 } 320 });//#saveForm发送提交请求 321 });//#saveButton点击事件 322 323 });//页面加载 324 325 </script> 326 </body> 327 </html>
Spring+SpringMVC+Mybatis+SVN 实现列表显示、分页查询的功能
原文:https://www.cnblogs.com/Joixiaowang/p/13058104.html