集成mybatis-plus,swagger,redis,异常处理,代码生成器等基础功能
springboot: 2.6.6 , springcloud: 2021.0.1 ,spring-cloud-alibaba: 2021.0.1.0 pom文件:
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.6</version>
<relativePath/>
</parent>
<artifactId>xxx</artifactId>
<name>xz</name>
<version>1.1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<spring-cloud.version>2021.0.1</spring-cloud.version>
<spring-cloud-alibaba.version>2021.0.1.0</spring-cloud-alibaba.version>
<mybatis-plus.version>3.4.0</mybatis-plus.version>
<jasypt.spring.boot.starter.version>2.0.0</jasypt.spring.boot.starter.version>
<fastjson.version>1.2.67</fastjson.version>
<jwt.version>0.9.1</jwt.version>
<swagger2.version>2.9.2</swagger2.version>
<io.swagger.version>1.5.22</io.swagger.version>
<hutool.version>5.4.2</hutool.version>
<poi-ooxml.version>4.1.2</poi-ooxml.version>
<redisson.version>3.13.6</redisson.version>
<velocity-engine-core.version>2.3</velocity-engine-core.version>
<skipTests>true</skipTests>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>${redisson.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>${jasypt.spring.boot.starter.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!--swagger2-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger2.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger2.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${io.swagger.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>${io.swagger.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi-ooxml.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity-engine-core.version}</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
</dependencies>
<build>
<finalName>xxxx</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
配置文件:
server:
port: 8080
spring:
servlet:
multipart:
max-file-size: 2048MB
max-request-size: 10240MB
jackson:
default-property-inclusion: non_null
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
mvc:
pathmatch:
matching-strategy: ant-path-matcher
redis:
password: ${redis.cluster.password}
cluster:
nodes: ${redis.cluster.nodes}
max-redirects: 3
lettuce:
pool:
max-idle: 16 #最大空闲连接 默认为8
max-active: 32 #最大连接数(使用负值表示没有限制) 默认为8
min-idle: 8 #最小空闲连接 默认为 0
max-wait: 5000ms #最大阻塞等待时间(使用负值表示没有限制) 默认为-1
datasource:
url: jdbc:mysql://${db.host}:${db.port}/${db.database}?characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&useSSL=true&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&tinyInt1isBit=false
username: ${db.username}
password: ${db.password}
#--------------------------- mybatis-plus-------------------------
mybatis-plus:
mapper-locations: classpath*:**/mapping/*.xml
global-config:
db-config:
id-type: auto
logic-delete-value: 1
logic-not-delete-value: 0
configuration:
map-underscore-to-camel-case: true
cache-enabled: true
lazyLoadingEnabled: true
multipleResultSetsEnabled: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
package ;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* Swagger配置
*/
@EnableSwagger2
@Configuration
@Profile({"dev","test","poc","future", "local"})
public class SwaggerConfig {
@Bean
public Docket authzApi() {
//增加头部参数
ParameterBuilder headerParam = new ParameterBuilder();
headerParam.name("token").description("token").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
/*ParameterBuilder appKeyParam = new ParameterBuilder();
appKeyParam.name("appKey").description("appKey").modelRef(new ModelRef("string")).parameterType("header").required(false).build();*/
List<Parameter> parameterList = new ArrayList<Parameter>();
parameterList.add(headerParam.build());
//parameterList.add(appKeyParam.build());
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo("接口文档","接口文档","1.0.0")) .select()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
//.apis(RequestHandlerSelectors.basePackage("com.*.*"))
.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
.paths(PathSelectors.any())
.build()
.groupName("v1.0.1")
.globalOperationParameters(parameterList).enable(true)
;
}
private ApiInfo apiInfo(String name, String description, String version) {
return new ApiInfoBuilder().title(name).description(description).version(version).build();
}
@Bean
public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
return new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof WebMvcRequestHandlerProvider ) {
customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
}
return bean;
}
private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
List<T> copy = mappings.stream()
.filter(mapping -> mapping.getPatternParser() == null)
.collect(Collectors.toList());
mappings.clear();
mappings.addAll(copy);
}
@SuppressWarnings("unchecked")
private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
try {
Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
field.setAccessible(true);
return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
};
}
}
RedisConfig:
package ;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
/**
* 管理缓存
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
return RedisCacheManager.create(factory);
}
/**
* RedisTemplate配置
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
redisTemplate.setConnectionFactory(factory);
return redisTemplate;
}
@Bean
public StringRedisTemplate strRedisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(factory);
return template;
}
}
MybatisPlusConfig:
package ;
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.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* MyBatisPlus配置
*/
@EnableTransactionManagement
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
}
CodeGenerator:
package ;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.List;
public class CodeGenerator {
private static String projectPath = "D:\\AAA";
private static String modularName = "bu";
public static GlobalConfig gc() {
GlobalConfig gc = new GlobalConfig();
gc.setOutputDir(projectPath);
gc.setAuthor("NIUBI");
gc.setOpen(false);
gc.setSwagger2(true);
return gc;
}
public static DataSourceConfig dsc() {
DataSourceConfig dsc = new DataSourceConfig();
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("");
dsc.setPassword("");
dsc.setUrl("jdbc:mysql://xx.xx.xxx:3306/ku?characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&useSSL=true&serverTimezone=Asia/Shanghai");
return dsc;
}
public static PackageConfig packageConfig(){
PackageConfig pc = new PackageConfig();
String standardModularPath = "";
if(StringUtils.isNotBlank(modularName)){
standardModularPath += "." + modularName;
}
pc.setParent(standardModularPath);
pc.setEntity("model");
pc.setMapper("dao");
pc.setXml("dao.mapping");
pc.setService("service");
pc.setController("controller");
pc.setServiceImpl("service.impl");
return pc;
}
public static void main(String[] args) {
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
mpg.setGlobalConfig(gc());
// 数据源配置
mpg.setDataSource(dsc());
// 包配置
PackageConfig pc = packageConfig();
mpg.setPackageInfo(pc);
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
// String templatePath = "/templates/mapper.xml.ftl";
String templatePath = "/templates/mapper.xml.vm";
List<FileOutConfig> focList = new ArrayList<>();
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return projectPath + "/" + pc.getParent().replaceAll("\\.", "/") + "/" + pc.getXml().replaceAll("\\.", "/") + "/" + tableInfo.getEntityName() + "Mapper.xml";
}
});
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
TemplateConfig templateConfig = new TemplateConfig();
templateConfig.setXml(null);
mpg.setTemplate(templateConfig);
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
//strategy.setTablePrefix("t_");
//strategy.setSuperEntityClass(BaseEntity.class);
//strategy.setSuperControllerClass(BaseController.class);
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
strategy.setInclude(
"需要生成的表"
);
strategy.setControllerMappingHyphenStyle(true);
mpg.setStrategy(strategy);
mpg.execute();
}
}
响应封装:
package ;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
@ApiModel(value = "返回信息", description = "返回信息")
public class Response<T> {
@ApiModelProperty(value = "状态码")
private Integer code;
@ApiModelProperty(value = "信息说明")
private String message;
@ApiModelProperty(value = "数据体")
private T data;
public static Response ok(String message) {
return new Response<>(0, message, null);
}
public static Response ok() {
return new Response<>(0, "操作成功", null);
}
public static <T> Response<T> data(T data) {
return new Response<>(0, "操作成功", data);
}
public static Response error(Integer code, String message) {
return new Response<>(code, message, null);
}
public static Response error(String message) {
return new Response<>(500, message, null);
}
public static Response error() {
return new Response<>(500, "操作失败", null);
}
}
自定义异常:
package ;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.lang3.builder.ToStringBuilder;
/**
* 自定义Exception
*
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class MyRestException extends RuntimeException {
private static final long serialVersionUID = 1L;
/**
* 自定义异常描述
*/
private String message;
/**
* 自定义异常code
*/
private Integer code =500;
public MyRestException(String message) {
this.message = message;
}
public MyRestException(String message, Throwable e) {
super(e.getMessage(), e);
this.message = message;
}
public MyRestException(Integer code, String message) {
this.message = message;
this.code = code;
}
public MyRestException(String message, Integer code) {
this.message = message;
this.code = code;
}
public MyRestException(Integer code, String message, Throwable e) {
super(e.getMessage(), e);
this.message = message;
this.code = code;
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
异常捕捉:
package ;
import Response;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 自定义异常
*/
@ExceptionHandler(MyRestException.class)
@ResponseBody
public Response handleRestException(MyRestException e) {
logger.info(e.getMessage(), e);
return Response.error(e.getCode(), e.getMessage());
}
@ExceptionHandler(RuntimeException.class)
@ResponseBody
public Response runtimeException(RuntimeException e) {
logger.error(ExceptionUtils.getStackTrace(e));
String message = e.getMessage();
return Response.error(500, message);
}
@ExceptionHandler(Exception.class)
@ResponseBody
public Response handleException(Exception e) {
logger.error(ExceptionUtils.getStackTrace(e));
return Response.error(500, e.getMessage());
}
}