参考资料
log4jdbc数据库访问日志框架使用(开源中国)
https://my.oschina.net/cloudcoder/blog/420510
log4jdbc使用介绍
https://blog.csdn.net/u013409283/article/details/79219858
LogBack 实例
https://my.oschina.net/u/943316/blog/802531
mybatis中对logback.xml的使用详解(对logback.xml的详解)
http://www.cnblogs.com/jirglt/archive/2012/10/19/2731456.html
Logback.xml模板
https://www.cnblogs.com/light-zhang/p/8744647.html
Spring boot 使用logback+log4jdbc打印sql日志
https://blog.csdn.net/zj7321/article/details/83144980
前言
使用Spring Boot进行开发时,我们为了调试方便,都需要输出sql语句,简单的日志打印方式,只能显示sql语句,并不能显示具体的占位符的内容,这篇文章主要讲解如何使用logback+log4jdbc打印sql日志并显示占位符内容
项目搭建不使用log4jdbc
1. 创建springboot项目,并引入web、jpa、mysql、lombok
<?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.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>logback-log4jdbc-jpa-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>logback-log4jdbc-jpa-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-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.application.yml文件配置
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
username: ehealth_user
password: FK7sJp92XF
url: jdbc:mysql://47.104.108.103:3309/eladmin?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
jpa:
show-sql: true
-
spring-jpa-show-sql: true 用于输出sql语句,默认为false,使用log4jdbc后可不加此配置
3.logback.xml日志文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="10 seconds" debug="false">
<!-- 项目名称 -->
<property name="PROJECT" value="demo" />
<!-- 日志路径 -->
<property name="PATH" value="/log" />
<!-- 控制台日志格式 -->
<property name="PATTERN_CONSOLE" value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}) - %gray(%msg%n)" />
<!-- 日志文件日志格式 -->
<property name="PATTERN_FILE" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" />
<!-- 日志文件的最大size -->
<property name="FILESIZE" value="50MB" />
<!-- 日志存储的历史天数 -->
<property name="MAXHISTORY" value="100" />
<!-- 输出到控制台 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder charset="utf-8">
<pattern>${PATTERN_CONSOLE}</pattern>
</encoder>
</appender>
<!-- error级别日志 输入到文件,按日期和文件大小 -->
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当天日志的存放路径及名称 -->
<file>${PATH}/${PROJECT}/${PROJECT}-error.log</file>
<!-- 日志输出格式 -->
<encoder charset="utf-8">
<pattern>${PATTERN_FILE}</pattern>
</encoder>
<!-- 拦截ERROR级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 日志滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 历史日志文件的存放路径和名称 -->
<fileNamePattern>${PATH}/${PROJECT}/${PROJECT}-error.%d.%i.log.zip</fileNamePattern>
<!-- 日志文件最大的保存历史 数量-->
<maxHistory>${MAXHISTORY}</maxHistory>
<!-- 日志滚动策略文件的大小,超过这个大小会新建一个文件,指定此配置必须在fileNamePattern配置%i -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- warn级别日志 输入到文件,按日期和文件大小 -->
<appender name="warn" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当天日志的存放路径及名称 -->
<file>${PATH}/${PROJECT}/${PROJECT}-warn.log</file>
<!-- 日志输出格式 -->
<encoder charset="utf-8">
<pattern>${PATTERN_FILE}</pattern>
</encoder>
<!-- 拦截ERROR级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 日志滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 历史日志文件的存放路径和名称 -->
<fileNamePattern>${PATH}/${PROJECT}/${PROJECT}-warn.%d.%i.log.zip</fileNamePattern>
<!-- 日志文件最大的保存历史 数量-->
<maxHistory>${MAXHISTORY}</maxHistory>
<!-- 日志滚动策略文件的大小,超过这个大小会新建一个文件,指定此配置必须在fileNamePattern配置%i -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- debug级别日志 输入到文件,按日期和文件大小 -->
<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当天日志的存放路径及名称 -->
<file>${PATH}/${PROJECT}/${PROJECT}-debug.log</file>
<!-- 日志输出格式 -->
<encoder charset="utf-8">
<pattern>${PATTERN_FILE}</pattern>
</encoder>
<!-- 拦截ERROR级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 日志滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 历史日志文件的存放路径和名称 -->
<fileNamePattern>${PATH}/${PROJECT}/${PROJECT}-debug.%d.%i.log.zip</fileNamePattern>
<!-- 日志文件最大的保存历史 数量-->
<maxHistory>${MAXHISTORY}</maxHistory>
<!-- 日志滚动策略文件的大小,超过这个大小会新建一个文件,指定此配置必须在fileNamePattern配置%i -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- info级别日志 输入到文件,按日期和文件大小 -->
<appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当天日志的存放路径及名称 -->
<file>${PATH}/${PROJECT}/${PROJECT}-info.log</file>
<!-- 日志输出格式 -->
<encoder charset="utf-8">
<pattern>${PATTERN_FILE}</pattern>
</encoder>
<!-- 拦截ERROR级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 日志滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 历史日志文件的存放路径和名称 -->
<fileNamePattern>${PATH}/${PROJECT}/${PROJECT}-info.%d.%i.log.zip</fileNamePattern>
<!-- 日志文件最大的保存历史 数量-->
<maxHistory>${MAXHISTORY}</maxHistory>
<!-- 日志滚动策略文件的大小,超过这个大小会新建一个文件,指定此配置必须在fileNamePattern配置%i -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!--普通日志输出到控制台-->
<root level="INFO">
<appender-ref ref="console" />
<appender-ref ref="error" />
<appender-ref ref="warn" />
<appender-ref ref="debug" />
<appender-ref ref="info" />
</root>
</configuration>
4.创建实体类Menu
package com.example.domain;
import lombok.Data;
import javax.persistence.*;
import java.util.Date;
/**
* @Author: jiangweifan
* @Date: 2019/3/19 14:14
* @Description:
*/
@Data
@Entity
@Table(name = "menu")
public class Menu {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Date createTime;
private String iFrame;
private String name;
private String component;
private String pid;
private String sort;
private String icon;
private String path;
}
5.创建MenuRepository进行数据库操作
package com.example.repository;
import com.example.domain.Menu;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/**
* @Author: jiangweifan
* @Date: 2019/3/19 14:20
* @Description:
*/
public interface MenuRepository extends JpaRepository<Menu, Long> {
}
6.创建MenuController
package com.example.controller;
import com.example.domain.Menu;
import com.example.repository.MenuRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @Author: jiangweifan
* @Date: 2019/3/19 14:21
* @Description:
*/
@RestController
@Slf4j
public class MenuController {
@Autowired
MenuRepository menuRepository;
@RequestMapping("/all")
public Menu all() {
return menuRepository.findById(10L).get();
}
}
7.启动项目并访问http://localhost:8080/all
控制台输出如下:
image
可见这种sql输出并不方便于我们的开发
项目搭建使用log4jdbc
基于上面的项目进行修改
1.pom文件引入log4jdbc-log4j2-jdbc4.1依赖
<!--监控sql日志-->
<dependency>
<groupId>org.bgee.log4jdbc-log4j2</groupId>
<artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
<version>1.16</version>
</dependency>
2.yml文件修改
spring:
datasource:
driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
username: ehealth_user
password: FK7sJp92XF
url: jdbc:log4jdbc:mysql://47.104.108.103:3309/eladmin?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
-
driver-class-name 使用 net.sf.log4jdbc.sql.jdbcapi.DriverSpy
-
url 中加入log4jdbc
-
不需要配置spring-jpa-show-sql
3.logback.xml修改
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="10 seconds" debug="false">
<!-- 项目名称 -->
<property name="PROJECT" value="demo" />
<!-- 日志路径 -->
<property name="PATH" value="/log" />
<!-- 控制台日志格式 -->
<property name="PATTERN_CONSOLE" value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}) - %gray(%msg%n)" />
<!-- 日志文件日志格式 -->
<property name="PATTERN_FILE" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" />
<!-- 日志文件的最大size -->
<property name="FILESIZE" value="50MB" />
<!-- 日志存储的历史天数 -->
<property name="MAXHISTORY" value="100" />
<!-- 输出到控制台 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder charset="utf-8">
<pattern>${PATTERN_CONSOLE}</pattern>
</encoder>
</appender>
<!-- error级别日志 输入到文件,按日期和文件大小 -->
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当天日志的存放路径及名称 -->
<file>${PATH}/${PROJECT}/${PROJECT}-error.log</file>
<!-- 日志输出格式 -->
<encoder charset="utf-8">
<pattern>${PATTERN_FILE}</pattern>
</encoder>
<!-- 拦截ERROR级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 日志滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 历史日志文件的存放路径和名称 -->
<fileNamePattern>${PATH}/${PROJECT}/${PROJECT}-error.%d.%i.log.zip</fileNamePattern>
<!-- 日志文件最大的保存历史 数量-->
<maxHistory>${MAXHISTORY}</maxHistory>
<!-- 日志滚动策略文件的大小,超过这个大小会新建一个文件,指定此配置必须在fileNamePattern配置%i -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- warn级别日志 输入到文件,按日期和文件大小 -->
<appender name="warn" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当天日志的存放路径及名称 -->
<file>${PATH}/${PROJECT}/${PROJECT}-warn.log</file>
<!-- 日志输出格式 -->
<encoder charset="utf-8">
<pattern>${PATTERN_FILE}</pattern>
</encoder>
<!-- 拦截ERROR级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 日志滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 历史日志文件的存放路径和名称 -->
<fileNamePattern>${PATH}/${PROJECT}/${PROJECT}-warn.%d.%i.log.zip</fileNamePattern>
<!-- 日志文件最大的保存历史 数量-->
<maxHistory>${MAXHISTORY}</maxHistory>
<!-- 日志滚动策略文件的大小,超过这个大小会新建一个文件,指定此配置必须在fileNamePattern配置%i -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- debug级别日志 输入到文件,按日期和文件大小 -->
<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当天日志的存放路径及名称 -->
<file>${PATH}/${PROJECT}/${PROJECT}-debug.log</file>
<!-- 日志输出格式 -->
<encoder charset="utf-8">
<pattern>${PATTERN_FILE}</pattern>
</encoder>
<!-- 拦截ERROR级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 日志滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 历史日志文件的存放路径和名称 -->
<fileNamePattern>${PATH}/${PROJECT}/${PROJECT}-debug.%d.%i.log.zip</fileNamePattern>
<!-- 日志文件最大的保存历史 数量-->
<maxHistory>${MAXHISTORY}</maxHistory>
<!-- 日志滚动策略文件的大小,超过这个大小会新建一个文件,指定此配置必须在fileNamePattern配置%i -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- info级别日志 输入到文件,按日期和文件大小 -->
<appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当天日志的存放路径及名称 -->
<file>${PATH}/${PROJECT}/${PROJECT}-info.log</file>
<!-- 日志输出格式 -->
<encoder charset="utf-8">
<pattern>${PATTERN_FILE}</pattern>
</encoder>
<!-- 拦截ERROR级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 日志滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 历史日志文件的存放路径和名称 -->
<fileNamePattern>${PATH}/${PROJECT}/${PROJECT}-info.%d.%i.log.zip</fileNamePattern>
<!-- 日志文件最大的保存历史 数量-->
<maxHistory>${MAXHISTORY}</maxHistory>
<!-- 日志滚动策略文件的大小,超过这个大小会新建一个文件,指定此配置必须在fileNamePattern配置%i -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!--普通日志输出到控制台-->
<root level="INFO">
<appender-ref ref="console" />
<appender-ref ref="error" />
<appender-ref ref="warn" />
<appender-ref ref="debug" />
<appender-ref ref="info" />
</root>
<!--监控sql日志输出 -->
<logger name="jdbc.sqlonly" level="INFO"/>
<logger name="jdbc.resultset" level="ERROR"/>
<logger name="jdbc.resultsettable" level="INFO"/>
<logger name="jdbc.connection" level="OFF"/>
<logger name="jdbc.sqltiming" level="OFF"/>
<logger name="jdbc.audit" level="OFF"/>
</configuration>
-
主要加入了监控sql文件的输出
<!--监控sql日志输出 -->
<logger name="jdbc.sqlonly" level="INFO"/>
<logger name="jdbc.resultset" level="ERROR"/>
<logger name="jdbc.resultsettable" level="INFO"/>
<logger name="jdbc.connection" level="OFF"/>
<logger name="jdbc.sqltiming" level="OFF"/>
<logger name="jdbc.audit" level="OFF"/>
-
对于log4jdbc的相关配置可参考顶部参考资料
4. 在resources目录下添加log4jdbc.log4j2.properties文件
# If you use SLF4J. First, you need to tell log4jdbc-log4j2 that you want to use the SLF4J logger
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
5. 启动项目,并访问http://localhost:8080/all
控制台输出如下
image
至此,使用log4jdbc打印sql输出已完成,关于log4jdbc的更多使用可参考参考资料进行学习
项目用到的menu数据库表文件
参考资料
log4jdbc数据库访问日志框架使用(开源中国)
https://my.oschina.net/cloudcoder/blog/420510
log4jdbc使用介绍
https://blog.csdn.net/u013409283/article/details/79219858
LogBack 实例
https://my.oschina.net/u/943316/blog/802531
mybatis中对logback.xml的使用详解(对logback.xml的详解)
http://www.cnblogs.com/jirglt/archive/2012/10/19/2731456.html
Logback.xml模板
https://www.cnblogs.com/light-zhang/p/8744647.html
Spring boot 使用logback+log4jdbc打印sql日志
https://blog.csdn.net/zj7321/article/details/83144980
前言
使用Spring Boot进行开发时,我们为了调试方便,都需要输出sql语句,简单的日志打印方式,只能显示sql语句,并不能显示具体的占位符的内容,这篇文章主要讲解如何使用logback+log4jdbc打印sql日志并显示占位符内容
项目搭建不使用log4jdbc
1. 创建springboot项目,并引入web、jpa、mysql、lombok
<?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.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>logback-log4jdbc-jpa-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>logback-log4jdbc-jpa-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-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.application.yml文件配置
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
username: ehealth_user
password: FK7sJp92XF
url: jdbc:mysql://47.104.108.103:3309/eladmin?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
jpa:
show-sql: true
-
spring-jpa-show-sql: true 用于输出sql语句,默认为false,使用log4jdbc后可不加此配置
3.logback.xml日志文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="10 seconds" debug="false">
<!-- 项目名称 -->
<property name="PROJECT" value="demo" />
<!-- 日志路径 -->
<property name="PATH" value="/log" />
<!-- 控制台日志格式 -->
<property name="PATTERN_CONSOLE" value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}) - %gray(%msg%n)" />
<!-- 日志文件日志格式 -->
<property name="PATTERN_FILE" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" />
<!-- 日志文件的最大size -->
<property name="FILESIZE" value="50MB" />
<!-- 日志存储的历史天数 -->
<property name="MAXHISTORY" value="100" />
<!-- 输出到控制台 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder charset="utf-8">
<pattern>${PATTERN_CONSOLE}</pattern>
</encoder>
</appender>
<!-- error级别日志 输入到文件,按日期和文件大小 -->
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当天日志的存放路径及名称 -->
<file>${PATH}/${PROJECT}/${PROJECT}-error.log</file>
<!-- 日志输出格式 -->
<encoder charset="utf-8">
<pattern>${PATTERN_FILE}</pattern>
</encoder>
<!-- 拦截ERROR级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 日志滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 历史日志文件的存放路径和名称 -->
<fileNamePattern>${PATH}/${PROJECT}/${PROJECT}-error.%d.%i.log.zip</fileNamePattern>
<!-- 日志文件最大的保存历史 数量-->
<maxHistory>${MAXHISTORY}</maxHistory>
<!-- 日志滚动策略文件的大小,超过这个大小会新建一个文件,指定此配置必须在fileNamePattern配置%i -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- warn级别日志 输入到文件,按日期和文件大小 -->
<appender name="warn" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当天日志的存放路径及名称 -->
<file>${PATH}/${PROJECT}/${PROJECT}-warn.log</file>
<!-- 日志输出格式 -->
<encoder charset="utf-8">
<pattern>${PATTERN_FILE}</pattern>
</encoder>
<!-- 拦截ERROR级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 日志滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 历史日志文件的存放路径和名称 -->
<fileNamePattern>${PATH}/${PROJECT}/${PROJECT}-warn.%d.%i.log.zip</fileNamePattern>
<!-- 日志文件最大的保存历史 数量-->
<maxHistory>${MAXHISTORY}</maxHistory>
<!-- 日志滚动策略文件的大小,超过这个大小会新建一个文件,指定此配置必须在fileNamePattern配置%i -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- debug级别日志 输入到文件,按日期和文件大小 -->
<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当天日志的存放路径及名称 -->
<file>${PATH}/${PROJECT}/${PROJECT}-debug.log</file>
<!-- 日志输出格式 -->
<encoder charset="utf-8">
<pattern>${PATTERN_FILE}</pattern>
</encoder>
<!-- 拦截ERROR级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 日志滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 历史日志文件的存放路径和名称 -->
<fileNamePattern>${PATH}/${PROJECT}/${PROJECT}-debug.%d.%i.log.zip</fileNamePattern>
<!-- 日志文件最大的保存历史 数量-->
<maxHistory>${MAXHISTORY}</maxHistory>
<!-- 日志滚动策略文件的大小,超过这个大小会新建一个文件,指定此配置必须在fileNamePattern配置%i -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- info级别日志 输入到文件,按日期和文件大小 -->
<appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当天日志的存放路径及名称 -->
<file>${PATH}/${PROJECT}/${PROJECT}-info.log</file>
<!-- 日志输出格式 -->
<encoder charset="utf-8">
<pattern>${PATTERN_FILE}</pattern>
</encoder>
<!-- 拦截ERROR级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 日志滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 历史日志文件的存放路径和名称 -->
<fileNamePattern>${PATH}/${PROJECT}/${PROJECT}-info.%d.%i.log.zip</fileNamePattern>
<!-- 日志文件最大的保存历史 数量-->
<maxHistory>${MAXHISTORY}</maxHistory>
<!-- 日志滚动策略文件的大小,超过这个大小会新建一个文件,指定此配置必须在fileNamePattern配置%i -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!--普通日志输出到控制台-->
<root level="INFO">
<appender-ref ref="console" />
<appender-ref ref="error" />
<appender-ref ref="warn" />
<appender-ref ref="debug" />
<appender-ref ref="info" />
</root>
</configuration>
4.创建实体类Menu
package com.example.domain;
import lombok.Data;
import javax.persistence.*;
import java.util.Date;
/**
* @Author: jiangweifan
* @Date: 2019/3/19 14:14
* @Description:
*/
@Data
@Entity
@Table(name = "menu")
public class Menu {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Date createTime;
private String iFrame;
private String name;
private String component;
private String pid;
private String sort;
private String icon;
private String path;
}
5.创建MenuRepository进行数据库操作
package com.example.repository;
import com.example.domain.Menu;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/**
* @Author: jiangweifan
* @Date: 2019/3/19 14:20
* @Description:
*/
public interface MenuRepository extends JpaRepository<Menu, Long> {
}
6.创建MenuController
package com.example.controller;
import com.example.domain.Menu;
import com.example.repository.MenuRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @Author: jiangweifan
* @Date: 2019/3/19 14:21
* @Description:
*/
@RestController
@Slf4j
public class MenuController {
@Autowired
MenuRepository menuRepository;
@RequestMapping("/all")
public Menu all() {
return menuRepository.findById(10L).get();
}
}
7.启动项目并访问http://localhost:8080/all
控制台输出如下:
image
可见这种sql输出并不方便于我们的开发
项目搭建使用log4jdbc
基于上面的项目进行修改
1.pom文件引入log4jdbc-log4j2-jdbc4.1依赖
<!--监控sql日志-->
<dependency>
<groupId>org.bgee.log4jdbc-log4j2</groupId>
<artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
<version>1.16</version>
</dependency>
2.yml文件修改
spring:
datasource:
driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
username: ehealth_user
password: FK7sJp92XF
url: jdbc:log4jdbc:mysql://47.104.108.103:3309/eladmin?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
-
driver-class-name 使用 net.sf.log4jdbc.sql.jdbcapi.DriverSpy
-
url 中加入log4jdbc
-
不需要配置spring-jpa-show-sql
3.logback.xml修改
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="10 seconds" debug="false">
<!-- 项目名称 -->
<property name="PROJECT" value="demo" />
<!-- 日志路径 -->
<property name="PATH" value="/log" />
<!-- 控制台日志格式 -->
<property name="PATTERN_CONSOLE" value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}) - %gray(%msg%n)" />
<!-- 日志文件日志格式 -->
<property name="PATTERN_FILE" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" />
<!-- 日志文件的最大size -->
<property name="FILESIZE" value="50MB" />
<!-- 日志存储的历史天数 -->
<property name="MAXHISTORY" value="100" />
<!-- 输出到控制台 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder charset="utf-8">
<pattern>${PATTERN_CONSOLE}</pattern>
</encoder>
</appender>
<!-- error级别日志 输入到文件,按日期和文件大小 -->
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当天日志的存放路径及名称 -->
<file>${PATH}/${PROJECT}/${PROJECT}-error.log</file>
<!-- 日志输出格式 -->
<encoder charset="utf-8">
<pattern>${PATTERN_FILE}</pattern>
</encoder>
<!-- 拦截ERROR级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 日志滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 历史日志文件的存放路径和名称 -->
<fileNamePattern>${PATH}/${PROJECT}/${PROJECT}-error.%d.%i.log.zip</fileNamePattern>
<!-- 日志文件最大的保存历史 数量-->
<maxHistory>${MAXHISTORY}</maxHistory>
<!-- 日志滚动策略文件的大小,超过这个大小会新建一个文件,指定此配置必须在fileNamePattern配置%i -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- warn级别日志 输入到文件,按日期和文件大小 -->
<appender name="warn" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当天日志的存放路径及名称 -->
<file>${PATH}/${PROJECT}/${PROJECT}-warn.log</file>
<!-- 日志输出格式 -->
<encoder charset="utf-8">
<pattern>${PATTERN_FILE}</pattern>
</encoder>
<!-- 拦截ERROR级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 日志滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 历史日志文件的存放路径和名称 -->
<fileNamePattern>${PATH}/${PROJECT}/${PROJECT}-warn.%d.%i.log.zip</fileNamePattern>
<!-- 日志文件最大的保存历史 数量-->
<maxHistory>${MAXHISTORY}</maxHistory>
<!-- 日志滚动策略文件的大小,超过这个大小会新建一个文件,指定此配置必须在fileNamePattern配置%i -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- debug级别日志 输入到文件,按日期和文件大小 -->
<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当天日志的存放路径及名称 -->
<file>${PATH}/${PROJECT}/${PROJECT}-debug.log</file>
<!-- 日志输出格式 -->
<encoder charset="utf-8">
<pattern>${PATTERN_FILE}</pattern>
</encoder>
<!-- 拦截ERROR级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 日志滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 历史日志文件的存放路径和名称 -->
<fileNamePattern>${PATH}/${PROJECT}/${PROJECT}-debug.%d.%i.log.zip</fileNamePattern>
<!-- 日志文件最大的保存历史 数量-->
<maxHistory>${MAXHISTORY}</maxHistory>
<!-- 日志滚动策略文件的大小,超过这个大小会新建一个文件,指定此配置必须在fileNamePattern配置%i -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- info级别日志 输入到文件,按日期和文件大小 -->
<appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当天日志的存放路径及名称 -->
<file>${PATH}/${PROJECT}/${PROJECT}-info.log</file>
<!-- 日志输出格式 -->
<encoder charset="utf-8">
<pattern>${PATTERN_FILE}</pattern>
</encoder>
<!-- 拦截ERROR级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 日志滚动策略 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 历史日志文件的存放路径和名称 -->
<fileNamePattern>${PATH}/${PROJECT}/${PROJECT}-info.%d.%i.log.zip</fileNamePattern>
<!-- 日志文件最大的保存历史 数量-->
<maxHistory>${MAXHISTORY}</maxHistory>
<!-- 日志滚动策略文件的大小,超过这个大小会新建一个文件,指定此配置必须在fileNamePattern配置%i -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!--普通日志输出到控制台-->
<root level="INFO">
<appender-ref ref="console" />
<appender-ref ref="error" />
<appender-ref ref="warn" />
<appender-ref ref="debug" />
<appender-ref ref="info" />
</root>
<!--监控sql日志输出 -->
<logger name="jdbc.sqlonly" level="INFO"/>
<logger name="jdbc.resultset" level="ERROR"/>
<logger name="jdbc.resultsettable" level="INFO"/>
<logger name="jdbc.connection" level="OFF"/>
<logger name="jdbc.sqltiming" level="OFF"/>
<logger name="jdbc.audit" level="OFF"/>
</configuration>
-
主要加入了监控sql文件的输出
<!--监控sql日志输出 -->
<logger name="jdbc.sqlonly" level="INFO"/>
<logger name="jdbc.resultset" level="ERROR"/>
<logger name="jdbc.resultsettable" level="INFO"/>
<logger name="jdbc.connection" level="OFF"/>
<logger name="jdbc.sqltiming" level="OFF"/>
<logger name="jdbc.audit" level="OFF"/>
-
对于log4jdbc的相关配置可参考顶部参考资料
4. 在resources目录下添加log4jdbc.log4j2.properties文件
# If you use SLF4J. First, you need to tell log4jdbc-log4j2 that you want to use the SLF4J logger
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
5. 启动项目,并访问http://localhost:8080/all
控制台输出如下
image
至此,使用log4jdbc打印sql输出已完成,关于log4jdbc的更多使用可参考参考资料进行学习
项目用到的menu数据库表文件
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for menu
-- ----------------------------
DROP TABLE IF EXISTS `menu`;
CREATE TABLE `menu` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`create_time` datetime DEFAULT NULL COMMENT '创建日期',
`i_frame` bit(1) DEFAULT NULL COMMENT '是否外链',
`name` varchar(255) DEFAULT NULL COMMENT '菜单名称',
`component` varchar(255) DEFAULT NULL COMMENT '组件',
`pid` bigint(20) NOT NULL COMMENT '上级菜单ID',
`sort` bigint(20) NOT NULL COMMENT '排序',
`icon` varchar(255) DEFAULT NULL COMMENT '图标',
`path` varchar(255) DEFAULT NULL COMMENT '链接地址',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
-- ----------------------------
-- Records of menu
-- ----------------------------
INSERT INTO `menu` VALUES ('1', '2018-12-18 15:11:29', '\0', '系统管理', null, '0', '1', 'system', 'system');
INSERT INTO `menu` VALUES ('2', '2018-12-18 15:14:44', '\0', '用户管理', 'system/user/index', '1', '2', 'peoples', 'user');
INSERT INTO `menu` VALUES ('3', '2018-12-18 15:16:07', '\0', '角色管理', 'system/role/index', '1', '3', 'role', 'role');
INSERT INTO `menu` VALUES ('4', '2018-12-18 15:16:45', '\0', '权限管理', 'system/permission/index', '1', '4', 'permission', 'permission');
INSERT INTO `menu` VALUES ('5', '2018-12-18 15:17:28', '\0', '菜单管理', 'system/menu/index', '1', '5', 'menu', 'menu');
INSERT INTO `menu` VALUES ('6', '2018-12-18 15:17:48', '\0', '系统监控', null, '0', '10', 'monitor', 'monitor');
INSERT INTO `menu` VALUES ('7', '2018-12-18 15:18:26', '\0', '操作日志', 'monitor/log/index', '6', '11', 'log', 'logs');
INSERT INTO `menu` VALUES ('8', '2018-12-18 15:19:01', '\0', '系统缓存', 'monitor/redis/index', '6', '13', 'redis', 'redis');
INSERT INTO `menu` VALUES ('9', '2018-12-18 15:19:34', '', 'SQL监控', null, '6', '14', 'sqlMonitor', 'http://api.auauz.net/druid');
INSERT INTO `menu` VALUES ('10', '2018-12-19 13:38:16', '\0', '组件管理', null, '0', '50', 'zujian', 'components');
INSERT INTO `menu` VALUES ('11', '2018-12-19 13:38:49', '\0', '图标库', 'components/IconSelect', '10', '51', 'icon', 'icon');
INSERT INTO `menu` VALUES ('12', '2018-12-24 20:37:35', '\0', '实时控制台', 'monitor/log/msg', '6', '15', 'codeConsole', 'msg');
INSERT INTO `menu` VALUES ('13', '2018-12-27 10:11:26', '\0', '三方工具', '', '0', '30', 'tools', 'tools');
INSERT INTO `menu` VALUES ('14', '2018-12-27 10:13:09', '\0', '邮件工具', 'tools/email/index', '13', '31', 'email', 'email');
INSERT INTO `menu` VALUES ('15', '2018-12-27 11:58:25', '\0', '富文本', 'components/Editor', '10', '52', 'fwb', 'tinymce');
INSERT INTO `menu` VALUES ('16', '2018-12-28 09:36:53', '\0', 'SM.MS图床', 'tools/picture/index', '13', '32', 'image', 'pictures');
INSERT INTO `menu` VALUES ('17', '2018-12-28 15:09:49', '', '项目地址', '', '0', '0', 'github', 'https://github.com/elunez/eladmin');
INSERT INTO `menu` VALUES ('18', '2018-12-31 11:12:15', '\0', '七牛云存储', 'tools/qiniu/index', '13', '33', 'qiniu', 'qiniu');
INSERT INTO `menu` VALUES ('19', '2018-12-31 14:52:38', '\0', '支付宝工具', 'tools/aliPay/index', '13', '34', 'alipay', 'aliPay');
INSERT INTO `menu` VALUES ('21', '2019-01-04 16:22:03', '\0', '多级菜单', '', '0', '900', 'menu', 'nested');
INSERT INTO `menu` VALUES ('22', '2019-01-04 16:23:29', '\0', '二级菜单1', 'nested/menu1/index', '21', '999', 'menu', 'menu1');
INSERT INTO `menu` VALUES ('23', '2019-01-04 16:23:57', '\0', '二级菜单2', 'nested/menu2/index', '21', '999', 'menu', 'menu2');
INSERT INTO `menu` VALUES ('24', '2019-01-04 16:24:48', '\0', '三级菜单1', 'nested/menu1/menu1-1', '22', '999', 'menu', 'menu1-1');
INSERT INTO `menu` VALUES ('27', '2019-01-07 17:27:32', '\0', '三级菜单2', 'nested/menu1/menu1-2', '22', '999', 'menu', 'menu1-2');
INSERT INTO `menu` VALUES ('28', '2019-01-07 20:34:40', '\0', '定时任务', 'system/timing/index', '1', '6', 'timing', 'timing');
INSERT INTO `menu` VALUES ('30', '2019-01-11 15:45:55', '\0', '代码生成', 'generator/index', '1', '8', 'dev', 'generator');
INSERT INTO `menu` VALUES ('32', '2019-01-13 13:49:03', '\0', '异常日志', 'monitor/log/errorLog', '6', '12', 'error', 'errorLog');
INSERT INTO `menu` VALUES ('33', '2019-03-08 13:46:44', '\0', 'Markdown', 'components/MarkDown', '10', '53', 'markdown', 'markdown');
INSERT INTO `menu` VALUES ('34', '2019-03-08 15:49:40', '\0', 'Yaml编辑器', 'components/YamlEdit', '10', '54', 'dev', 'yaml');
欢迎关注公众号,后续文章更新通知,一起讨论技术问题 。