工程规划

为了统一配置和代码解耦,我们对代码重新进行了整理和规划。

重新规划后,代码结构如下:

kitty-pom: 统一管理 Maven 版本,打包配置

kitty-common: 公共代码模块,主要放置工具类

kitty-core: 核心代码模块,主要封装公共业务模块

kitty-admin: 后台管理模块,包含用户、角色、菜单管理等

kitty-boot: Spring Boot 启动模块,包含一些全局配置信息

优化详情

kitty-core

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

kitty-admin

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

kitty-boot

1. 添加 kitty-common 依赖。

<dependency>
<groupId>com.louis</groupId>
<artifactId>kitty-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>

2. 依赖父 pom

kitty-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 进行打包。

参考资料

http://maven.apache.org

https://www.yiibai.com/maven/

源码下载

后端:https://gitee.com/liuge1988/kitty

前端:https://gitee.com/liuge1988/kitty-ui.git


作者:朝雨忆轻尘
出处:https://www.cnblogs.com/xifengxiaoma/
版权所有,欢迎转载,转载请注明原文作者及出处。

Spring Boot + Spring Cloud 实现权限管理系统 后端篇(九):代码整理优化的更多相关文章

  1. Spring Boot + Spring Cloud 实现权限管理系统 后端篇(二十五):Spring Security 版本

    在线演示 演示地址:http://139.196.87.48:9002/kitty 用户名:admin 密码:admin 技术背景 到目前为止,我们使用的权限认证框架是 Shiro,虽然 Shiro ...

  2. Spring Boot + Spring Cloud 实现权限管理系统 后端篇(一):Kitty 系统介绍

    在线演示 演示地址:http://139.196.87.48:9002/kitty 用户名:admin 密码:admin 温馨提示: 有在演示环境删除数据的童鞋们,如果可以的话,麻烦动动小指,右键头像 ...

  3. Spring Boot + Spring Cloud 实现权限管理系统 后端篇(二十三):配置中心(Config、Bus)

    在线演示 演示地址:http://139.196.87.48:9002/kitty 用户名:admin 密码:admin 技术背景 如今微服务架构盛行,在分布式系统中,项目日益庞大,子项目日益增多,每 ...

  4. Spring Boot + Spring Cloud 实现权限管理系统 后端篇(二十):服务熔断(Hystrix、Turbine)

    在线演示 演示地址:http://139.196.87.48:9002/kitty 用户名:admin 密码:admin 雪崩效应 在微服务架构中,由于服务众多,通常会涉及多个服务层级的调用,而一旦基 ...

  5. Spring Boot + Spring Cloud 实现权限管理系统 后端篇(十九):服务消费(Ribbon、Feign)

    技术背景 上一篇教程中,我们利用Consul注册中心,实现了服务的注册和发现功能,这一篇我们来聊聊服务的调用.单体应用中,代码可以直接依赖,在代码中直接调用即可,但在微服务架构是分布式架构,服务都运行 ...

  6. Spring Boot + Spring Cloud 实现权限管理系统 后端篇(十八):注册中心(Spring Cloud Consul)

    什么是 Consul Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其它分布式服务注册与发现的方案,Consul 的方案更“一站式”,内置了服务注册与 ...

  7. Spring Boot + Spring Cloud 实现权限管理系统 后端篇(十六):容器部署项目

    容器部署项目 这一章我们引入docker,采用docker容器的方式部署我们的项目. 首先需要有一个linux环境,并且安装 java 和 maven 以及 docker 环境,这个教程多如牛毛,不再 ...

  8. Spring Boot + Spring Cloud 实现权限管理系统 后端篇(十五):系统服务监控

    系统服务监控 新建监控工程 新建Spring Boot项目,取名 kitty-monitor,结构如下. 添加项目依赖 添加 spring boot admin 的相关依赖. pom.xml < ...

  9. Spring Boot + Spring Cloud 实现权限管理系统 后端篇(十四):项目打包部署

    项目打包部署 安装MySQL镜像 注意:如果使用docker镜像安装MySQL,也需要在前端部署主机安装MySQL,因为备份还原功能是使用MySQL的本地命令进行操作的. 下载镜像 执行以下命令,拉取 ...

  10. Spring Boot + Spring Cloud 实现权限管理系统 后端篇(十三):系统备份还原

    系统备份还原 在很多时候,我们需要系统数据进行备份还原.我们这里就使用MySql的备份还原命令实现系统备份还原的功能. 新建工程 新建一个maven项目,并添加相关依赖,可以用Spring boot脚 ...

随机推荐

  1. 从晶体管到web浏览器

    几年前写了这个,想放到网上,招聘很困难,很多现代计算机科学教育真的很糟,很难找到懂得现代计算机堆栈的第一(基本)原理的人. 如果我曾经再次得到了12周的自由,我会提供这个作为课余学习的play,我也想 ...

  2. (转)Application, Session, Cookie, Viewstate, Cache对象用法和区别

    ================================================================================         1.Applicati ...

  3. spring之IOC和DI实现

    Spring核心思想 : IOC控制反转 DI依赖注入 AOP切面编程 IOC思想: 场景描述: 在没有加入spring框架之前我们调取业务层时需要创建对象,例如:  接口名   变量名=new  接 ...

  4. bootstrap1.1

    <!DOCTYPE html>   <html>   <head>   <meta charset="utf-8" />   < ...

  5. C++ const方法及对象

    一.整体代码 01.cpp #include <iostream> using namespace std; class Test { public: Test(int x) : x_(x ...

  6. Cannot retrieve metalink for repository: epel/x86_64. Please verify its path and try again 问题分析

    Cannot retrieve metalink for repository: epel/x86_64. Please verify its path and try again Loaded pl ...

  7. python threading模块2

    Thread 是threading模块中最重要的类之一,可以使用它来创建线程.有两种方式来创建线程:一种是通过继承Thread类,重写它的run方法:另一种是创建一个threading.Thread对 ...

  8. Winform解决界面重绘闪烁的问题

    在窗体或用户控件中重写CreateParams protected override CreateParams CreateParams { get { CreateParams cp = base. ...

  9. 常用Yum镜像源

    163网易的yum源 wget http://mirrors.163.com/.help/CentOS6-Base-163.repo sohu的yum源 wget http://mirrors.soh ...

  10. [SDOI2011]消耗战(虚树+树形动规)

    虚树dp 虚树的主要思想: 不遍历没用的的节点以及没用的子树,从而使复杂度降低到\(\sum\limits k\)(k为询问的节点的总数). 所以怎么办: 只把询问节点和其LCA放入询问的数组中. 1 ...