为了统一配置和代码解耦,我们对代码重新进行了整理和规划。
重新规划后,代码结构如下:
kitty-pom: 统一管理 Maven 版本,打包配置
kitty-common: 公共代码模块,主要放置工具类
kitty-core: 核心代码模块,主要封装公共业务模块
kitty-admin: 后台管理模块,包含用户、角色、菜单管理等
kitty-boot: Spring Boot 启动模块,包含一些全局配置信息
1. 新建 kitty-core 工程,把 kitty-admin 工程 page 包下的内容 迁移到 kitty-core 工程 page 包内。
2. 添加 kitty-common 依赖
<dependency>
<groupId>com.louis</groupId>
<artifactId>kitty-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
3. 添加统一控制器接口返回结果封装 HttpResult
HttpResult.java
package com.louis.kitty.core.http;
public class HttpResult {
private int code;
private String msg;
private Object data;
public static HttpResult error() {
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
}
public static HttpResult error(String msg) {
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
}
public static HttpResult error(int code, String msg) {
HttpResult r = new HttpResult();
r.setCode(code);
r.setMsg(msg);
return r;
}
public static HttpResult ok(String msg) {
HttpResult r = new HttpResult();
r.setMsg(msg);
return r;
}
public static HttpResult ok(Object data) {
HttpResult r = new HttpResult();
r.setData(data);
return r;
}
public static HttpResult ok() {
return new HttpResult();
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
4. 添加通用CURD接口
CurdService.java
package com.louis.kitty.core.service;
import java.util.List;
import com.louis.kitty.core.page.PageRequest;
import com.louis.kitty.core.page.PageResult;
/**
* 通用CURD接口
*/
public interface CurdService<T> {
/**
* 保存操作
* @param record
* @return
*/
int save(T record);
/**
* 更新操作
* @param record
* @return
*/
int update(T record);
/**
* 删除操作
* @param record
* @return
*/
int delete(T record);
/**
* 批量删除操作
* @param entities
*/
int delete(List<T> records);
/**
* 根据ID查询
* @param id
* @return
*/
T findById(Long id);
/**
* 分页查询
* 这里统一封装了分页请求和结果,避免直接引入具体框架的分页对象, 如MyBatis或JPA的分页对象
* 从而避免因为替换ORM框架而导致服务层、控制层的分页接口也需要变动的情况,替换ORM框架也不会
* 影响服务层以上的分页接口,起到了解耦的作用
* @param pageRequest 自定义,统一分页查询请求
* @return PageResult 自定义,统一分页查询结果
*/
PageResult findPage(PageRequest pageRequest);
}
5. 依赖父 pom
1. 添加 kitty-common 依赖。
<dependency>
<groupId>com.louis</groupId>
<artifactId>kitty-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
2. 删除 page 包内容。
3. 把 Controller 的返回结果替换为 HttpResult 。
4. Service 接口统一继承 CurdService 接口。
5. 服务实现类,增删改查通用代码示例。
package com.louis.kitty.admin.sevice.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.louis.kitty.admin.dao.SysUserMapper;
import com.louis.kitty.admin.model.SysUser;
import com.louis.kitty.admin.sevice.SysUserService;
import com.louis.kitty.core.page.PageRequest;
import com.louis.kitty.core.page.PageResult;
import com.louis.kitty.core.page.PageUtils;
@Service
public class SysUserServiceImpl implements SysUserService {
@Autowired
private SysUserMapper sysUserMapper;
@Override
public int save(SysUser record) {
return sysUserMapper.insertSelective(record);
}
@Override
public int update(SysUser record) {
return sysUserMapper.updateByPrimaryKeySelective(record);
}
@Override
public int delete(SysUser record) {
return sysUserMapper.deleteByPrimaryKey(record.getUserId());
}
@Override
public int delete(List<SysUser> records) {
for(SysUser record:records) {
delete(record);
}
return 1;
}
@Override
public SysUser findById(Long id) {
return sysUserMapper.selectByPrimaryKey(id);
}
@Override
public PageResult findPage(PageRequest pageRequest) {
return PageUtils.getPageResult(pageRequest, getPageInfo(pageRequest));
}
/**
* 调用分页插件完成分页
* @param pageQuery
* @return
*/
private PageInfo<SysUser> getPageInfo(PageRequest pageRequest) {
int pageNum = pageRequest.getPageNum();
int pageSize = pageRequest.getPageSize();
PageHelper.startPage(pageNum, pageSize);
List<SysUser> sysMenus = sysUserMapper.findPage();
return new PageInfo<SysUser>(sysMenus);
}
@Override
public List<SysUser> findAll() {
return sysUserMapper.findAll();
}
}
6. 依赖父 pom
1. 添加 kitty-common 依赖。
<dependency>
<groupId>com.louis</groupId>
<artifactId>kitty-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
2. 依赖父 pom
1. 新建 kitty-pom 工程,添加 pom.xml。
2. 添加预依赖,汇总版本属性
3. 添加 Maven 子模块,添加打包配置
对分页功能重新进行了封装,让实现分页功能极为快速简便。
封装之后,服务层调用示例(服务层一行代码调用实现分页):
方法1说明
如果遵守约定,DAO查询方法为findPage,那么只需要传入对应的Mapper, 调用MybatisPageHelper直接返回分页数据即可。
方法2说明
如果方法名不为findPage,则传入相应的方法名即可,还可以根据查询参数过滤后进行分页,如下面就是根据名词name查询菜单,并进行分页。
@Override
public PageResult findPage(PageRequest pageRequest) {
return MybatisPageHelper.findPage(pageRequest, sysMenuMapper);
}
@Override
public PageResult findPageByName(PageRequest pageRequest, String name) {
return MybatisPageHelper.findPage(pageRequest, sysMenuMapper, "findPageByName", name);
}
MybatisPageHelper 统一封装了分页逻辑,在Dao层写好之后,服务层只需要一行代码就可以实现分页功能。
这是怎么实现的呢,无非是先获取查询参数设置到分页插件,然后利用反射调用Mapper对应的查询方法,最后将结果封装到PageResult返回。
MybatisPageHelper.java
package com.louis.kitty.core.page;
import java.util.List;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.louis.kitty.common.utils.ReflectionUtils;
/**
* MyBatis 分页查询助手
* @author Louis
* @date Aug 19, 2018
*/
public class MybatisPageHelper {
public static final String findPage = "findPage";
/**
* 分页查询, 约定查询方法名为 “findPage”
* @param pageRequest 分页请求
* @param mapper Dao对象,MyBatis的 Mapper
* @param args 方法参数
* @return
*/
public static PageResult findPage(PageRequest pageRequest, Object mapper) {
return findPage(pageRequest, mapper, findPage);
}
/**
* 调用分页插件进行分页查询
* @param pageRequest 分页请求
* @param mapper Dao对象,MyBatis的 Mapper
* @param queryMethodName 要分页的查询方法名
* @param args 方法参数
* @return
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static PageResult findPage(PageRequest pageRequest, Object mapper, String queryMethodName, Object... args) {
// 设置分页参数
int pageNum = pageRequest.getPageNum();
int pageSize = pageRequest.getPageSize();
PageHelper.startPage(pageNum, pageSize);
// 利用反射调用查询方法
Object result = ReflectionUtils.invoke(mapper, queryMethodName, args);
return getPageResult(pageRequest, new PageInfo((List) result));
}
/**
* 将分页信息封装到统一的接口
* @param pageRequest
* @param page
* @return
*/
private static PageResult getPageResult(PageRequest pageRequest, PageInfo<?> pageInfo) {
PageResult pageResult = new PageResult();
pageResult.setPageNum(pageInfo.getPageNum());
pageResult.setPageSize(pageInfo.getPageSize());
pageResult.setTotalSize(pageInfo.getTotal());
pageResult.setTotalPages(pageInfo.getPages());
pageResult.setContent(pageInfo.getList());
return pageResult;
}
}
选择 kitty-pom 下的 pom.xml 进行打包。