一、前言
在前面一篇文章中:SpringBoot 系列教程(一百零六):SpringBoot封装企业通用Swagger配置 ,写了如何封装企业级Swagger常用配置为Starter启动器,为了验证我们自身封装的swagger-spring-boot-strater
可用性,本章节专门选用技术栈 SpringBoot2.3.7.RELEASE+Swagger+Mybatis Plus3.4.2
搭建一套增删改查的简单代码,SpringBoot2.3.7.RELEASE为稳定版本,Mybatis Plus3.4.2 最新版本。
二、环境搭建
1. pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.thinkingcao</groupId>
<artifactId>springboot-swagger-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-swagger-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>
<dependencies>
<!-- 自身封装的swagger -->
<dependency>
<groupId>com.swagger</groupId>
<artifactId>swagger-spring-boot-strater</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<mainClass>com.thinkingcao.SwaggerDemoApplication</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2. application.yml
#应用程序名称
spring:
application:
name: springboot-swagger-demo
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/swagger-api-demo?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: 123456
profiles:
active: dev
#MyBatis-Plus配置
mybatis-plus:
configuration:
#是否开启自动驼峰命名规则(camel case)映射,# 该参数不能和mybatis-plus.config-location同时存在
map-underscore-to-camel-case: true
##全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存,默认为 true。
cache-enabled: false
auto-mapping-behavior: full
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#指定mapper对应xml文件位置
mapper-locations: classpath*:mapper/**/*Mapper.xml
#指定别名实体类扫描路径
type-aliases-package: com.thinkingcao.entity
#扫描枚举类 # 支持统配符 * 或者 ; 分割
type-enums-package: com.thinkingcao.enums
global-config:
# 逻辑删除配置
db-config:
#逻辑未删除值,默认为0
logic-not-delete-value: 0
#逻辑已删除值,默认为1
logic-delete-value: 1
#全局逻辑删除实体字段名
logic-delete-field: deleted
#设置全局主键生成策略
id-type: auto
#全局表名配置,前缀
table-prefix: t_
#Swagger配置信息
project:
swagger:
#启用、禁用
enable: true
#标题
title: SpringBoot整合Swagger构建Api文档
#描述
desc: 简单优雅的restfull风格接口文档
#版本
version: 1.0.0
#扫包配置
base-package: com.thinkingcao.controller
三、项目配置
1. 乐观锁、分页插件配置MybatisPlusConfig
package com.thinkingcao.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 分页插件:PaginationInnerInterceptor
* 乐观锁: OptimisticLockerInnerInterceptor
*/
@Configuration
@MapperScan("com.thinkingcao.mapper")
public class MybatisPlusConfig {
/**
* 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//向Mybatis过滤器链中添加分页拦截器
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
//添加乐观锁
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
//还可以添加i他的拦截器
return interceptor;
}
@Bean
public ConfigurationCustomizer configurationCustomizer() {
return configuration -> configuration.setUseDeprecatedExecutor(false);
}
}
2. 自动填充时间配置MyMetaObjectHandler
package com.thinkingcao.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
* 自动填充时间配置
*/
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill ....");
// 起始版本 3.3.0(推荐使用)
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill ....");
// 起始版本 3.3.0(推荐)
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
}
3. Entity配置
package com.thinkingcao.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@TableId(value = "id",type = IdType.AUTO) // 自增ID
private Long id;
private String name;
private Integer age;
private String email;
@TableField(fill = FieldFill.INSERT)
private Date createTime; //自动填充时间
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime; //自动填充时间
private Integer version; //乐观锁
@TableLogic //逻辑删除
private Integer deleted;
}
4. UserMapper
package com.thinkingcao.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.thinkingcao.entity.User;
public interface UserMapper extends BaseMapper<User> {
}
5. UserService
package com.thinkingcao.service;
import com.thinkingcao.entity.User;
import com.thinkingcao.mapper.UserMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* @desc:
* @author: cao_wencao
* @date: 2021-04-18 12:54
*/
@Service
public class UserService {
@Resource
private UserMapper userMapper;
/**
* 查询多个
* @return
*/
public List<User> selectListUser(){
List<User> users = userMapper.selectList(null);
return users;
}
/**
* 查询单个
* @return
*/
public User selectOneUser(String id){
User user = userMapper.selectById(id);
return user;
}
/**
* 增加
* @return
*/
public Boolean insertUser(User user){
int insertResult = userMapper.insert(user);
if (insertResult >=1){
return true;
}
return false;
}
/**
* 修改
* @return
*/
public Boolean updateUser(User user){
int updateById = userMapper.updateById(user);
if (updateById >=1){
return true;
}
return false;
}
/**
* 删除
* @return
*/
public Boolean deleteUser(String id){
int deleteById = userMapper.deleteById(id);
if (deleteById >=1){
return true;
}
return false;
}
}
6. UserController
package com.thinkingcao.controller;
import com.thinkingcao.enums.ErrorCode;
import com.thinkingcao.entity.User;
import com.thinkingcao.result.BaseResult;
import com.thinkingcao.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @desc:
* @author: cao_wencao
* @date: 2021-04-18 12:58
*/
@RequestMapping("/user/api")
@RestController
@Api(value = "用户信息API接口",tags="用户信息API接口实现")
@Slf4j
public class UserController {
@Autowired
private UserService userService;
/**
* 查询多个
* @return
*/
@GetMapping("/selectListUser")
@ApiOperation(value = "查询批量用户")
public BaseResult selectListUser(){
List<User> userList = userService.selectListUser();
return BaseResult.success(userList);
}
/**
* 查询单个
* @return
*/
@GetMapping("/selectOneUser/{id}")
@ApiOperation(value = "查询单个用户")
public BaseResult selectOneUser(@PathVariable("id") String id){
User user = userService.selectOneUser(id);
return BaseResult.success(user);
}
/**
* 增加
* @return
*/
@PostMapping("/insertUser")
@ApiOperation(value = "新增用户")
public BaseResult insertUser(@RequestBody User user){
Boolean result = userService.insertUser(user);
if (result){
return BaseResult.success(result);
}
return BaseResult.error(ErrorCode.DB_ERROR);
}
/**
* 修改
* @return
*/
@PostMapping("/updateUser")
@ApiOperation(value = "修改用户")
public BaseResult updateUser(@RequestBody User user){
Boolean result = userService.updateUser(user);
if (result){
return BaseResult.success(result);
}
return BaseResult.error(ErrorCode.DB_ERROR);
}
/**
* 删除
* @return
*/
@PostMapping("/deleteUser/{id}")
@ApiOperation(value = "删除用户")
public BaseResult deleteUser(@PathVariable("id") String id){
Boolean result = userService.deleteUser(id);
if (result){
return BaseResult.success(result);
}
return BaseResult.error(ErrorCode.DB_ERROR);
}
}
7. 公共类
- BaseResult
package com.thinkingcao.result;
import com.thinkingcao.enums.ErrorCode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.util.Objects;
@ApiModel
public class BaseResult<T> implements Serializable {
@ApiModelProperty("返回状态码")
protected Integer code;
@ApiModelProperty("返回信息")
protected String message;
@ApiModelProperty("返回对象")
protected T data;
public BaseResult() {
}
public BaseResult(ErrorCode success) {
this((ErrorCode)success, (T) null);
}
public BaseResult(ErrorCode success, T data) {
this.code = success.getCode();
this.message = success.getMessage();
this.data = data;
}
public BaseResult(Integer code, String message) {
this.code = code;
this.message = message;
}
public BaseResult(Integer code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
public static BaseResult success() {
return new BaseResult(ErrorCode.SUCCESS);
}
public static <T> BaseResult<T> success(T data) {
return new BaseResult(ErrorCode.SUCCESS, data);
}
public static BaseResult error() {
return new BaseResult(ErrorCode.ERROR);
}
public static BaseResult error(ErrorCode code) {
return new BaseResult(code);
}
public static BaseResult error(ErrorCode code, Throwable ex) {
BaseResult baseResult = new BaseResult(code);
return baseResult;
}
public Integer getCode() {
return this.code;
}
public T getData() {
return this.data;
}
public void setCode(Integer code) {
this.code = code;
}
public void setMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setData(T data) {
this.data = data;
}
@Override
public String toString() {
return "BaseResult{" +
"code=" + code +
", message='" + message + '\'' +
", data=" + data +
'}';
}
@Override
public int hashCode() {
return Objects.hash(code, message, data);
}
}
- ErrorCode
package com.thinkingcao.enums;
public enum ErrorCode {
SUCCESS(200, "成功"),
DB_ERROR(510, "操作数据库失败"),
ERROR(511, "操作失败"),
SYSTEM_ERROR(500, "系统异常"),
VALID_ARGUMENT(400, "参数有误");
private Integer code;
private String message;
private ErrorCode(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return this.code;
}
public String getMessage() {
return this.message;
}
}
8. 启动类
package com.thinkingcao;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SwaggerDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SwaggerDemoApplication.class, args);
}
}
四、数据库脚本
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '姓名',
`age` int(11) DEFAULT NULL COMMENT '年龄',
`email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '邮箱',
`create_time` datetime(0) DEFAULT NULL COMMENT '创建时间',
`update_time` datetime(0) DEFAULT NULL COMMENT '更新时间',
`deleted` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '删除标记',
`version` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '乐观锁版本号version',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES (1, 'Jone', 18, 'test1@baomidou.com', NULL, NULL, '0', NULL);
INSERT INTO `t_user` VALUES (2, 'Jack', 20, 'test2@baomidou.com', NULL, NULL, '0', NULL);
INSERT INTO `t_user` VALUES (3, 'Tom', 28, 'test3@baomidou.com', NULL, NULL, '0', NULL);
INSERT INTO `t_user` VALUES (4, 'Sandy', 21, 'test4@baomidou.com', NULL, NULL, '0', NULL);
INSERT INTO `t_user` VALUES (5, 'Billie', 24, 'test5@baomidou.com', NULL, NULL, '1', NULL);
INSERT INTO `t_user` VALUES (6, '曹构', 22, '617271837', '2021-04-18 17:11:45', '2021-04-18 17:11:45', '0', '1');
SET FOREIGN_KEY_CHECKS = 1;
五、运行测试
http://127.0.0.1:8080/swagger-ui.html#