SpringBoot集成log4jdbc定制sql输出

参考资料 
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');

欢迎关注公众号,后续文章更新通知,一起讨论技术问题 。

公众号二维码

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值