目录
编写实体类、Dao层接口和Mapper配置文件,并编写测试类进行测试
第一个Springboot应用,数据库采用Mysql,连接池采用Druid DataSource,持久层框架采用Mybatis,Restful接口返回,并且增加了日志处理,日志采用Slf4j + logback,整个项目是通过maven来构建的,在下面的阅读过程中,有注解不了解的可以自己去百度学习一下,也可以通过idea直接查看源码的注解,先来看一下整个工程的目录结构。
修改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 http://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.1.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.wyq</groupId>
<artifactId>first-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>first-demo</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.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.17</version>
</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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.12</version>
</dependency>
<!-- 工具类 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
数据库配置
创建user表
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`age` int(11) NULL DEFAULT NULL,
`birth_day` datetime(0) NULL DEFAULT NULL,
`is_married` bit(1) NULL DEFAULT NULL,
`salary` decimal(10, 2) NULL DEFAULT NULL,
`insert_time` timestamp(0) NULL DEFAULT NULL,
`update_time` timestamp(0) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(0),
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 20 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
修改application.properties文件
#mybatis
#为实体对象所在的包,跟数据库表一一对应
mybatis.typeAliasesPackage=com.wyq.firstdemo.entity
#mapper文件的位置
mybatis.mapperLocations=classpath:mappers/*.xml
#数据库
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/wyq_db?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 下面为连接池的补充设置,应用到上面所有数据源中
# 初始化大小,最小,最大
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
# 配置获取连接等待超时的时间
spring.datasource.maxWait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.timeBetweenEvictionRunsMillis=60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.minEvictableIdleTimeMillis=300000
# 校验SQL,Oracle配置 spring.datasource.validationQuery=SELECT 1 FROM DUAL,如果不配validationQuery项,则下面三项配置无用
spring.datasource.validationQuery=select '1' from dual
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
# 打开PSCache,并且指定每个连接上PSCache的大小
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
#spring.datasource.filters=stat,wall,log4j
spring.datasource.filters=stat,wall,slf4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 合并多个DruidDataSource的监控数据
spring.datasource.useGlobalDataSourceStat=true
#druid
spring.datasource.druid.username=wyq
spring.datasource.druid.password=Admin@1234
spring.datasource.druid.logSlowSql=true
编写Druid配置类
如果使用@slf4j注解之后,无法直接使用log日志对象,请在idea上安装lombok插件,lombok可以大大提高你的编码效率,使你的编码更加优雅(使用Lombok来优雅的编码)
package com.wyq.firstdemo.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
/**
* @ClassName DruidConfig
* @Description druid参数配置
* @Author weiyanqiang
* @Date 2019/6/22 16:49
* @Version 1.0
*/
@Slf4j
@Data
@Configuration
@ConfigurationProperties(prefix = "spring.datasource.druid")
public class DruidConfig {
private String username;
private String password;
private String logSlowSql;
@Bean
public ServletRegistrationBean druidServlet() {
ServletRegistrationBean reg = new ServletRegistrationBean();
reg.setServlet(new StatViewServlet());
reg.addUrlMappings("/druid/*");
reg.addInitParameter("loginUsername", username);
reg.addInitParameter("loginPassword", password);
reg.addInitParameter("logSlowSql", logSlowSql);
return reg;
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druid() {
DruidDataSource dataSource = new DruidDataSource();
return dataSource;
}
}
到这边数据库的配置基本完成,在FirstDemoApplication类上增加一个@ComponentScan("com.wyq"),然后启动服务,访问http://localhost:8083/druid/login.html网址就可以访问druid后台信息,这边的8083是我的服务端口,如果大家不改动的话应该是8080,大家根据自己的实际情况填写,用户名和密码就是配置文件里面配置的spring.datasource.druid.username和spring.datasource.druid.password。
如果有sql运行,我们可以通过sql监控来进行查看
编写实体类、Dao层接口和Mapper配置文件,并编写测试类进行测试
新建UserEntity实体类
package com.wyq.firstdemo.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.util.Date;
/**
* @ClassName UserEntity
* @Description 用户实体类
* @Author weiyanqiang
* @Date 2019/6/23 22:28
* @Version 1.0
*/
@Getter
@Setter
@ToString
public class UserEntity {
private int id;
private String name;
private int age;
/**
* 解决json时间格式化的问题
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date birthDay;
private boolean isMarried;
private float salary;
}
新建UserMapper接口
package com.wyq.firstdemo.dao;
import com.wyq.firstdemo.entity.UserEntity;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
// @Repository这个注解写不写无所谓,不写的话在idea的service中自动注入编译器会报错,但是不影响运行
@Repository
public interface UserMapper {
int insert(UserEntity userEntity);
int insertList(@Param("userEntityList") List<UserEntity> userEntityList);
int deleteById(int id);
int update(UserEntity userEntity);
UserEntity queryById(int id);
List<UserEntity> queryAll();
}
增加完mapper接口之后,我们需要在启动类上增加一个@MapperScan注解,把mapper扫描进去。
新建UserMapper.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wyq.firstdemo.dao.UserMapper">
<resultMap id="BaseResultMap" type="com.wyq.firstdemo.entity.UserEntity">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="age" jdbcType="INTEGER" property="age" />
<result column="birth_day" jdbcType="DATE" property="birthDay" />
<result column="is_married" jdbcType="BIT" property="isMarried" />
<result column="salary" jdbcType="DECIMAL" property="salary" />
</resultMap>
<sql id="Base_Column_List">
id, name, age, birth_day, is_married, salary
</sql>
<insert id="insert" parameterType="com.wyq.firstdemo.entity.UserEntity">
insert into user (name, age, birth_day, is_married, salary, insert_time, update_time)
values
(#{name}, #{age}, #{birthDay}, #{isMarried}, #{salary}, now(), now())
</insert>
<insert id="insertList">
insert into user (name, age, birth_day, is_married, salary, insert_time, update_time)
values
<foreach collection="userEntityList" item="userEntity" separator=",">
(#{userEntity.name}, #{userEntity.age}, #{userEntity.birthDay}, #{userEntity.isMarried}, #{userEntity.salary}, now(), now())
</foreach>
</insert>
<delete id="deleteById" parameterType="int">
delete from user
where
id = #{id}
</delete>
<update id="update" parameterType="com.wyq.firstdemo.entity.UserEntity">
update user
set name = #{name}, age = #{age}, birth_day = #{birthDay}, is_married = #{isMarried}, salary = #{salary}
where id = #{id}
</update>
<select id="queryById" parameterType="int" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from user
where
id = #{id}
</select>
<select id="queryAll" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from user
</select>
</mapper>
到这边数据访问层就写好了,接下来我们编写测试类来测试一下每个方法的正确性
新建UserMapperTest测试类
package com.wyq.firstdemo.dao;
import com.wyq.firstdemo.entity.UserEntity;
import com.wyq.firstdemo.util.DateUtil;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName UserMapperTest
* @Description TODO
* @Author weiyanqiang
* @Date 2019/6/24 22:41
* @Version 1.0
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {
@Autowired
private UserMapper userMapper;
@Test
public void testInsert() {
UserEntity userEntity = new UserEntity();
userEntity.setName("wyq");
userEntity.setAge(28);
userEntity.setBirthDay(DateUtil.strToDateTime("1992-12-28 14:00:00"));
userEntity.setMarried(true);
userEntity.setSalary(200000);
userMapper.insert(userEntity);
}
@Test
public void testInsertList() {
List<UserEntity> userEntityList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
UserEntity userEntity = new UserEntity();
userEntity.setName("test" + i);
userEntity.setAge(28 + i);
userEntity.setBirthDay(DateUtil.strToDateTime("1992-12-28 14:00:00"));
userEntity.setMarried(true);
userEntity.setSalary(180000);
userEntityList.add(userEntity);
}
userMapper.insertList(userEntityList);
}
@Test
public void testDeleteById() {
userMapper.deleteById(1);
}
@Test
public void testUpdate() {
UserEntity userEntity = new UserEntity();
userEntity.setId(2);
userEntity.setName("fy");
userEntity.setAge(28);
userEntity.setBirthDay(DateUtil.strToDateTime("1992-02-03 14:00:00"));
userEntity.setMarried(true);
userEntity.setSalary(180000);
userMapper.update(userEntity);
}
@Test
public void testQueryById() {
UserEntity userEntity = userMapper.queryById(2);
System.out.println(userEntity);
}
@Test
public void testQueryAll() {
List<UserEntity> userEntityList = userMapper.queryAll();
System.out.println(userEntityList);
}
}
点击每个测试方法左侧边栏的三角符号,选择运行,就可以运行这个测试方法了
编写service层和controller层代码
编写service层
新建UserService接口
package com.wyq.firstdemo.service;
import com.wyq.firstdemo.entity.UserEntity;
import java.util.List;
/**
* 用户服务类
*/
public interface UserService {
int insert(UserEntity userEntity);
int insertList(List<UserEntity> userEntityList);
int deleteById(int id);
int update(UserEntity userEntity);
UserEntity queryById(int id);
List<UserEntity> queryAll();
}
新建UserService接口实现类,UserServiceImpl类
package com.wyq.firstdemo.service.impl;
import com.wyq.firstdemo.common.ServerResponse;
import com.wyq.firstdemo.dao.UserMapper;
import com.wyq.firstdemo.entity.UserEntity;
import com.wyq.firstdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @ClassName UserServiceImpl
* @Description TODO
* @Author weiyanqiang
* @Date 2019/6/24 10:14
* @Version 1.0
*/
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public int insert(UserEntity userEntity) {
return userMapper.insert(userEntity);
}
@Override
public int insertList(List<UserEntity> userEntityList) {
return userMapper.insertList(userEntityList);
}
@Override
public int deleteById(int id) {
return userMapper.deleteById(id);
}
@Override
public int update(UserEntity userEntity) {
return userMapper.update(userEntity);
}
@Override
public UserEntity queryById(int id) {
return userMapper.queryById(id);
}
@Override
public List<UserEntity> queryAll() {
return userMapper.queryAll();
}
}
编写controller层
在编写controller层之前,我们需要定义服务器接口返回统一格式-ServerResponse
新建ResponseCode枚举类
这个枚举类用来定义返回的状态码和信息
package com.wyq.firstdemo.enums;
/**
* @ClassName ResponseCode
* @Description 返回状态
* @Author weiyanqiang
* @Date 2019/6/26 11:24
* @Version 1.0
*/
public enum ResponseCode {
SUCCESS(0, "SUCCESS"),
ERROR(1, "ERROR"),
ILLEGAL_ARGUMENT(2, "ILLEGAL_ARGUMENT"),
EXCEPTION(-1, "EXCEPTION");
private final int code;
private final String desc;
ResponseCode(int code, String desc) {
this.code = code;
this.desc = desc;
}
public int getCode() {
return code;
}
public String getDesc() {
return desc;
}
}
新建ServerResponse接口返回格式类
package com.wyq.firstdemo.common;
import com.wyq.firstdemo.enums.ResponseCode;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import java.io.Serializable;
/**
* @ClassName ServerResponse
* @Description 返回前段数据封装
* @Author weiyanqiang
* @Date 2019/6/26 13:04
* @Version 1.0
*/
//当序列化Json对象时,如果是null的对象,key也会消失
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class ServerResponse<T> implements Serializable {
private int status;
private String msg;
private T data;
private ServerResponse(int status){
this.status = status;
}
private ServerResponse(int status,T data){
this.status = status;
this.data = data;
}
private ServerResponse(int status,String msg, T data){
this.status = status;
this.msg = msg;
this.data = data;
}
private ServerResponse(int status,String msg){
this.status = status;
this.msg = msg;
}
@JsonIgnore
public boolean isSuccess(){
return this.status == ResponseCode.SUCCESS.getCode();
}
public int getStatus() {
return status;
}
public String getMsg() {
return msg;
}
public T getData() {
return data;
}
public static <T> ServerResponse<T> createBySuccess(){
return new ServerResponse<T>(ResponseCode.SUCCESS.getCode());
}
public static <T> ServerResponse<T> createBySuccessMessage(String msg){
return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(),msg);
}
public static <T> ServerResponse<T> createBySuccess(T data){
return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(),data);
}
public static <T> ServerResponse<T> createBySuccess(String msg,T data){
return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(),msg,data);
}
public static <T> ServerResponse<T> createByError(){
return new ServerResponse<T>(ResponseCode.ERROR.getCode(),ResponseCode.ERROR.getDesc());
}
public static <T> ServerResponse<T> createByErrorMessage(String errorMessage){
return new ServerResponse<T>(ResponseCode.ERROR.getCode(),errorMessage);
}
public static <T> ServerResponse<T> createByIllegalArgument(String errorMessage){
return new ServerResponse<T>(ResponseCode.ILLEGAL_ARGUMENT.getCode(),errorMessage);
}
public static <T> ServerResponse<T> createByException(String errorMessage){
return new ServerResponse<T>(ResponseCode.EXCEPTION.getCode(),errorMessage);
}
}
到这边,Restful接口返回的类我们就定义好了
新增UserController类
package com.wyq.firstdemo.controller;
import com.wyq.firstdemo.common.ServerResponse;
import com.wyq.firstdemo.entity.UserEntity;
import com.wyq.firstdemo.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @ClassName UserController
* @Description 用户控制类
* @Author weiyanqiang
* @Date 2019/6/25 21:41
* @Version 1.0
*/
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/insert")
public ServerResponse<String> insert(@RequestBody UserEntity userEntity) {
try {
userService.insert(userEntity);
} catch (Exception e) {
log.error("insert user fail!", e);
return ServerResponse.createByErrorMessage("insert user fail!");
}
return ServerResponse.createBySuccess();
}
@PostMapping("/insert/all")
public ServerResponse<String> insertList(@RequestBody List<UserEntity> userEntityList) {
try {
userService.insertList(userEntityList);
} catch (Exception e) {
log.error("insert user fail!", e);
return ServerResponse.createByErrorMessage("insert user fail!");
}
return ServerResponse.createBySuccess();
}
@DeleteMapping("/delete/{id}")
public ServerResponse<String> delete(@PathVariable("id") String strId) {
try {
int id = Integer.parseInt(strId);
userService.deleteById(id);
} catch (NumberFormatException e) {
log.error("illegal argument!", e);
return ServerResponse.createByIllegalArgument("illegal argument!");
} catch (Exception e) {
log.error("delete user by id fail!", e);
return ServerResponse.createByErrorMessage("insert user fail!");
}
return ServerResponse.createBySuccess();
}
@PostMapping("/update")
public ServerResponse<String> update(@RequestBody UserEntity userEntity) {
try {
userService.update(userEntity);
} catch (Exception e) {
log.error("update user fail!", e);
return ServerResponse.createByErrorMessage("update user fail!");
}
return ServerResponse.createBySuccess();
}
@GetMapping("/list/{id}")
public ServerResponse<UserEntity> query(@PathVariable("id") String strId) {
UserEntity userEntity = null;
try {
int id = Integer.parseInt(strId);
userEntity = userService.queryById(id);
} catch (NumberFormatException e) {
log.error("illegal argument!",e);
return ServerResponse.createByIllegalArgument("illegal argument!");
} catch (Exception e) {
log.error("query user by id fail!", e);
return ServerResponse.createByErrorMessage("query user by id fail!");
}
return ServerResponse.createBySuccess(userEntity);
}
@GetMapping("/list")
public ServerResponse<List<UserEntity>> queryAll() {
List<UserEntity> list = null;
try {
list = userService.queryAll();
} catch (Exception e) {
log.error("query all user fail!", e);
return ServerResponse.createByErrorMessage("query all user fail!");
}
return ServerResponse.createBySuccess(list);
}
}
到这边,所有的代码就表写完成了,接下里我们来配置日志管理
配置日志管理
新建logback-spring.xml文件
大家可以根据项目修改LOG_HOME的value值,还有开发环境建议把下面这个注释掉,使用控制台输出日志,方便定位,真实环境,把控制台注释挂掉,改为日志文件输出
<?xml version="1.0" encoding="UTF-8"?>
<!--dev env-->
<configuration>
<!--
fileError对应error级别,文件名以log-error-xxx.log形式命名
fileWarn对应warn级别,文件名以log-warn-xxx.log形式命名
fileInfo对应info级别,文件名以log-info-xxx.log形式命名
fileDebug对应debug级别,文件名以log-debug-xxx.log形式命名
stdout将日志信息输出到控制上,为方便开发测试使用
-->
<contextName>data_server</contextName>
<property name="LOG_HOME" value="wyq_log" />
<property name="log.maxHistory" value="1" />
<property name="log.lever" value="info" />
<appender name="fileError" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_HOME}/log_error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<MaxHistory>${log.maxHistory}</MaxHistory>
<!-- 配置日志文件不能超过100M,若超过100M,日志文件会以索引0开始-->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern>
<!--<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>-->
<charset>utf-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>error</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="fileWarn" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/log_warn.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<MaxHistory>${log.maxHistory}</MaxHistory>
<!-- 配置日志文件不能超过100M,若超过100M,日志文件会以索引0开始-->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern>
<!--<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>-->
<charset>utf-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="fileInfo" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/log_info.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<MaxHistory>${log.maxHistory}</MaxHistory>
<!-- 配置日志文件不能超过100M,若超过100M,日志文件会以索引0开始-->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern>
<!--<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>-->
<charset>utf-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!--encoder 默认配置为PatternLayoutEncoder-->
<encoder>
<!--<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern>-->
<pattern>%date{yyyy-MM-dd HH:mm:ss} | %highlight(%p) | %boldYellow(%c) | %M:%boldGreen(%L) | %m%n</pattern>
<!--<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>-->
<charset>utf-8</charset>
</encoder>
</appender>
<logger name="org.springframework" level="${log.lever}" />
<!-- 生产环境下,将此级别配置为适合的级别,以免日志文件太多或影响程序性能 -->
<root level="INFO">
<!--<appender-ref ref="fileError" />
<appender-ref ref="fileWarn" />
<appender-ref ref="fileInfo" />-->
<appender-ref ref="STDOUT" />
</root>
</configuration>
修改application.properties文件
在application.properties文件中,新增如下配置
#日志
logging.config=classpath:logback-spring.xml
到这边整个项目就表写完成了,接下大家可以通过postman进行测试。
代码已经上传到GitHub,有需要可以自己去下载
https://github.com/colar2017/springboot-first-demo