前一篇博客中使用LayUI实现了列表页面和编辑页面的显示交互,但列表页面table渲染的数据是固定数据,本篇博客主要是将固定数据变成数据库数据。
一、项目框架
首先要解决的是项目框架问题,搭建什么样的框架比较合适,优缺点是什么,扩展性、可读性等方面都要考虑,本项目的框架也是百度参考借鉴网友的,不管是Java还是C#的项目思想都差不多也都是可以互相借鉴的,下图是项目结构图,可能后面还会根据需要再进一步的修改完善。
上面目录结构中主要包含8个包,下面对这几个包进行简单介绍。
com.example:存在main函数类
com.example.config:配置类包,例如druid多数据源配置类
com.example.controller:存放controller
com.example.dao:与数据库交互层,存放mapper接口
com.example.entity:实体层,这个与com.example.pojo有点类似,不过两个还是有区别的,pojo层主要是与数据库单个数据表对应,entity可能是其他对象的抽象,比如多个表联合查询组成的行对应的类、或者前端页面显示对应的类、一对多、多对多关系。
com.example.pojo:数据库表的对应类
com.example.service:业务服务接口层,定义服务接口,优势是什么呢,这样在Controller中注入的是service接口,是面向接口的编程,如果服务的具体实现改变了也不影响其他注入类。
com.example.service.impl:实现服务接口,业务逻辑的具体实现
com.example.utils:基础类、工具类层
二、集成日志
项目使用的log4j2日志框架,由于SpringBoot自带的有日志框架,所以需要先排除掉,然后在引入log4j2日志。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
可以在application.properties中设置log4j2的相关配置或者创建log4j2.xml放在application.properties同目录下。这里在创建的log4j2.xml中设置日志存放位置在D:\log\logs,在该目录下可以看下日志文件。
二、集成mybatis
集成mybatis主要是引入两个依赖,一个是mysql的,一个是mybatis的。
<!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
项目是使用的xml方式管理sql,所以在该项目的resource目录下创建了mybatis目录,子目录mapper存放sql映射文件,mybatis-config.xml放mybatis的配置,同时还需要在application.properties设置数据库信息、mybatis文件目录信息。
#mysql
spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver
#spring.datasource.url = jdbc:mysql://localhost:3306/mybatis
spring.datasource.url =jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username = root
spring.datasource.password = 123456 #mybatis
mybatis.type-aliases-package=com.example.model
mybatis.config-location=classpath:mybatis/mybatis-config.xml
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
三、集成分页pagehelper
集成pagehelper这里有两种方式,一是spring集成方式,二是SpringBoot集成方式,可参考:https://www.cnblogs.com/1315925303zxz/p/7364552.html 。这里使用的是第一种,另外在这里遇到了一个问题,就是分页操作之后能查出数据但PageInfo的total值一直是0,原来是忘记在mybatis-config.xml配置pagehelper插件并要设置rowBoundsWithCount=true。
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>3.4.2</version>
</dependency>
<?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>
<typeAliases>
<typeAlias alias="Integer" type="java.lang.Integer" />
<typeAlias alias="Long" type="java.lang.Long" />
<typeAlias alias="HashMap" type="java.util.HashMap" />
<typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" />
<typeAlias alias="ArrayList" type="java.util.ArrayList" />
<typeAlias alias="LinkedList" type="java.util.LinkedList" />
</typeAliases>
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- 方言 -->
<property name="dialect" value="mysql"/>
<!-- 该参数默认为false -->
<!-- 设置为true时,使用RowBounds分页会进行count查询 -->
<property name="rowBoundsWithCount" value="true"/>
</plugin>
</plugins>
</configuration>
四、数据分页实现
1.首先数据库准备数据
这里在数据表中插入了12条数据。
2.分页
layui的table填充的数据有4个字段,code、msg、count、data,所以在PageDataResult中定义也定义了4个属性。
package com.example.utils; import java.util.List; public class PageDataResult {
//总记录数量
private Integer totals;
//当前页数据列表
private List<?> list; private Integer code=200; private String msg=""; public String getMsg() {
return msg;
} public void setMsg(String msg) {
this.msg = msg;
} public PageDataResult() {
} public PageDataResult( Integer totals,
List<?> list) {
this.totals = totals;
this.list = list;
} public Integer getTotals() {
return totals;
} public void setTotals(Integer totals) {
this.totals = totals;
} public List<?> getList() {
return list;
} public void setList(List<?> list) {
this.list = list;
} public Integer getCode() {
return code;
} public void setCode(Integer code) {
this.code = code;
} @Override public String toString() {
return "PageDataResult{" + "totals=" + totals + ", list=" + list
+ ", code=" + code + '}';
}
}
3.分页实现
主要实现方法也比较简单,使用pagehelper进行分页,然后将结果设置到PageDataResult。
@Override
public PageDataResult getUsers(UserSearchDTO userSearch) { PageDataResult pdr = new PageDataResult();
PageHelper.startPage(userSearch.getPage(), userSearch.getLimit(),true);
List<User> urList = userMapper.getUsers(userSearch);
logger.debug("urList:"+urList.size());
// 获取分页查询后的数据
PageInfo<User> pageInfo = new PageInfo<>(urList);
// 设置获取到的总记录数total:
logger.debug("page:"+userSearch.getPage()+"limit:"+userSearch.getLimit()+"总行数:"+pageInfo.getTotal());
pdr.setTotals(Long.valueOf(pageInfo.getTotal()).intValue());
pdr.setList(urList);
return pdr; }
4.替换固定数据
上一博客是将列表数据写成固定的,这里进行了替换,分页之后返回PageDataResult。
@RequestMapping(value = "/getUsers", method = RequestMethod.GET)
@ResponseBody
public PageDataResult getUsers(@RequestParam("page") Integer page,
@RequestParam("limit") Integer limit,@RequestParam(value="keyword",required=false) String keyword) {
logger.debug("分页查询用户列表!,查询条件keyword:"+keyword+"page:" + page+",每页记录数量limit:" + limit); PageDataResult pdr = new PageDataResult();
try {
if (null == page) {
page = 1;
}
if (null == limit) {
limit = 10;
}
UserSearchDTO userSearch=new UserSearchDTO(page,limit,keyword);
// 获取用户和角色列表
pdr = userService.getUsers(userSearch);
logger.debug("用户列表查询=pdr:" + pdr);
logger.debug("用户列表查询数量:" + pdr.getList().size());
} catch (Exception e) {
e.printStackTrace();
logger.error("用户列表查询异常!", e);
}
return pdr;
}
五、优化
由于从数据库返回的user表的sex数据是0、1,所以需要转成男、女,使用了table列的templet,同时id列通过hide=true进行了隐藏,又由于PageDataResult返回结果的key的名字与table所要求的不一致,又使用了response进行映射。下面代码是目前最新的user.js代码,后续可能还会更新。
var table;
var layer;
layui.use([ 'layer', 'table', 'element' ], function() {
table = layui.table;
layer = layui.layer;
// 执行一个 table 实例
table.render({
elem : '#user',
height:350,
url : '/user/getUsers',
method: 'get', //默认:get请求
page :true, // 开启分页
request: {
pageName: 'page' //页码的参数名称,默认:page
,limitName: 'limit' //每页数据量的参数名,默认:limit
},response:{
statusName: 'code' //数据状态的字段名称,默认:code
,statusCode: 200 //成功的状态码,默认:0
,countName: 'totals' //数据总数的字段名称,默认:count
,dataName: 'list' //数据列表的字段名称,默认:data
},
cols : [ [ // 表头
{
fixed : 'left',
type : 'checkbox'
}, {
field : 'id',
title : 'ID',
width : 80,
fixed : 'left',
hide:true
}, {
field : 'name',
title : '姓名',
width : 80
},
{
field : 'age',
title : '年龄',
width : 80
},
{
field : 'sex',
title : '性别',
width : 80,
templet : function(d) {
if (d.sex == 1) {
return '男';
} else if (d.sex == 0) {
return '女';
}
}
},{
title : '操作',
width : 200,
align : 'center',
toolbar : '#tools'
} ] ] }); // 监听工具条
table.on('tool(tools)', function(obj) { // 注:tool是工具条事件名,test是table原始容器的属性
var data = obj.data // 获得当前行数据
, layEvent = obj.event; // 获得 lay-event 对应的值
if ('edit' == layEvent) {
addUser(data.id)
} else if ('del' == layEvent) {
del(data.id);
}
});
}); function queryUser(){
var keyword = $("#keyword").val();
table.reload('user', {
where : {
keyword : keyword
},
page : {
curr : 1
}
});
} var index;
function addUser(id) {
index = parent.layer.open({
type : 2,
title : "用户信息",
area: ['550px', '400px'],
content : '/user/edit?id=' + id
});
layer.full(index);
} function del(id) {
parent.layer.open({
type : 1,
content : '<div style="padding: 20px 80px;">确定删除记录?</div>',
btn : [ '确定', '取消' ],
yes : function(index, layero) {
$.ajax({
url : "/user/delete",
data : {
"id" : id
},
dataType : "text",
success : function(data) {
if(data==0){
layer.msg("删除成功!");
layer.close(index);
queryUser();
}else{
layer.msg("删除失败!");
}
},
error : function() {
}
});
}
}); } /**
* 获取选中数据
*/
function getDatas(){
var checkStatus = table.checkStatus('user');
var data = checkStatus.data;
var id = "";
for(var i=0;i<data.length;i++){
id += data[i].id;
if(i<data.length-1){
id += ",";
}
}
if(data.length != 0){
alert(id);
// del(id);
}
}
六.小结
目前把java部分的项目框架搭建了起来,也集成了日志、mybatis、分页插件pagehelper,实现了table页面动态数据分页显示,后续就是将新增、编辑、删除几个功能实现,同时还要注意删除功能,删除用户后可能还要删除用户与角色关联表,会涉及到事务操作,后续也会加进来。