SSM+Swagger+plus+mysql+jwt+lombok+logback-spring.xml架构模板
项目结构
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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>springproject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springproject</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-spring-web</artifactId>
<version>2.7.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.28</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.2</version>
</dependency>
<!--redisson-->
<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>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.30</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml
server:
port: 8081
spring:
datasource:
#driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://IP:3306/demo?useUnicode=true&characterEncoding=utf8&timezone=GMT+8
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
redis:
host: ip
port: 6379
password: 自己的
mybatis-plus:
mapper-locations: mapper/*Mapper.xml
type-aliases-package: com.example.demowx.domain
global-config:
db-config:
id-type: auto #主键自增策略
MyBatisPlusConfig.class plus配置
package com.example.springproject.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @auther renzhong
* @description
* @date
*/
@Configuration
public class MyBatisPlusConfig {
/**
* mybatis-plus分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
return paginationInterceptor;
}
}
SwaggerConfig.class swagger配置
package com.example.springproject.config;
import io.swagger.annotations.ApiOperation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* @auther renzhong
* @description
* @date
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.groupName("demo")
.apiInfo(getApiInfo())
.select()
//设置basePackage会将包下的所有被@Api标记类的所有方法作为api
.apis(RequestHandlerSelectors.basePackage("com.example.springproject.controller"))
//只有标记了@ApiOperation的方法才会暴露出给swagger
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.paths(PathSelectors.regex("/api/.*")).build();
}
private ApiInfo getApiInfo(){
return new ApiInfoBuilder()
.title("API接口文档")
.description("www.baidu.com")
.termsOfServiceUrl("http://localhost:8081/swagger-ui.html")
.version("2.0")
.build();
}
}
domain 配置
package com.example.springproject.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "video")
public class Video implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id",type = IdType.AUTO)
private Integer id;
/**
* 视频标题
*/
private String titile;
/**
* 概述
*/
private String summary;
/**
* 封面图
*/
private String coverImg;
/**
* 时长
*/
private Integer videoNum;
/**
* 价格,分
*/
private Integer price;
/**
* create_time
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 0表示未启用 1表示使用
*/
private Integer online;
/**
* 评分 默认8.7,最高10
*/
private BigDecimal point;
}
mapper 配置
package com.example.springproject.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.springproject.domain.Video;
public interface VideoMapper extends BaseMapper<Video> {
}
service 配置
package com.example.springproject.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.springproject.domain.Video;
public interface IVideoService extends IService<Video> {
}
service.impl配置
package com.example.springproject.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.springproject.domain.Video;
import com.example.springproject.mapper.VideoMapper;
import com.example.springproject.service.IVideoService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional(timeout = 300)
public class IVideoServiceImpl extends ServiceImpl<VideoMapper, Video> implements IVideoService {
}
controller
package com.example.springproject.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.springproject.domain.Video;
import com.example.springproject.service.IVideoService;
import com.example.springproject.utils.ResponseVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
@Api(tags = "视频controller层")
@RestController
@RequestMapping("/api/video")
public class VideoController {
@Resource
private IVideoService videoService;
/**
* 新增或编辑
*/
@PostMapping("/save")
public ResponseVO save(@RequestBody Video video){
videoService.save(video);
return new ResponseVO(200,"success",null);
}
/**
* 删除
*/
@DeleteMapping("/delete")
public ResponseVO delete(int id){
return null;
}
/**
* 查询
*/
@ApiOperation(value = "根据视频ID查询",notes = "根据视频ID查询")
@ApiImplicitParam(value = "根据视频ID查询",name = "id",required = true,paramType = "path",dataTypeClass = Integer.class)
@GetMapping("/find/{id}")
public ResponseVO find(@PathVariable("id") Integer id){return new ResponseVO(200,"success",null);
}
@PutMapping("/update/{id}")
public ResponseVO updateVideo(@PathVariable("id")Integer id,@RequestBody Video video){
video.setId(id);
videoService.updateById(video);
return new ResponseVO(200,"success",null);
}
/**
* 分页查询
*/
@GetMapping("/list")
public ResponseVO list(
@RequestParam(required = false, defaultValue = "0") int pageNumber,
@RequestParam(required = false, defaultValue = "10") int pageSize) {
//分页构造器
Page<Video> page = new Page<Video>(pageNumber,pageSize);
//条件构造器
QueryWrapper<Video> queryWrapperw = new QueryWrapper<Video>();
IPage<Video> ip = videoService.page(page);
//执行分页
List<Video> list = ip.getRecords();
//返回结果
return new ResponseVO(200,"success",list);
}
}
多环境增加日志
注意 切换环境,只需要在application.yml主配置文件中指定即可,例: spring.profiles.active = dev
logback-spring.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--引入默认的一些设置-->
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<!--web信息-->
<logger name="org.springframework.web" level="info"/>
<!--写入日志到控制台的appender,用默认的,但是要去掉charset,否则windows下tomcat下乱码-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_PATH_DEV" value="D:/logs/boot-dev"/>
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_PATH_TEST" value="/logs/boot-test"/>
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_PATH_PROD" value="/logs/boot-prod"/>
<!--写入日志到文件的appender-->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名,每天一个文件-->
<FileNamePattern>${LOG_PATH}.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!--写入日志到文件的appender-->
<appender name="FILEDEV" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名,每天一个文件-->
<FileNamePattern>${LOG_PATH_DEV}.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!--异步到文件-->
<appender name="asyncFileAppender" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>500</queueSize>
<appender-ref ref="FILE"/>
</appender>
<!--异步到文件-->
<appender name="asyncFileAppenderdev" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>500</queueSize>
<appender-ref ref="FILEDEV"/>
</appender>
<!--生产环境:打印控制台和输出到文件-->
<springProfile name="prod">
<root level="info">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="asyncFileAppender"/>
</root>
</springProfile>
<!--开发环境:打印控制台-->
<springProfile name="dev">
<!-- 打印sql -->
<logger name="com.example.springproject.mapper" level="DEBUG"/>
<root level="DEBUG">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="asyncFileAppenderdev"/>
</root>
</springProfile>
<!--测试环境:打印控制台-->
<springProfile name="test">
<root level="info">
<appender-ref ref="CONSOLE"/>
</root>
</springProfile>
</configuration>