这篇里面我们最终要实现的效果是:
日志里面直接输出的SQL语句是带上传入的参数,直接从日志复制出来就可以使用的SQL语句。
首先在原项目上,在pom.xml里加入依赖:
<!--监控sql日志--> <dependency> <groupId>org.bgee.log4jdbc-log4j2</groupId> <artifactId>log4jdbc-log4j2-jdbc4.1</artifactId> <version>1.16</version> </dependency>
新增 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
在application.yml文件里面稍作修改:
#服务端口 server: port: 8055 spring: datasource: # driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy # url: jdbc:mysql://localhost:3306/testdemo?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull url: jdbc:log4jdbc:mysql://localhost:3306/testdemo?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull hikari: # springboot 2.0 整合了hikari ,据说这是目前性能最好的java数据库连接池 username: root password: root minimum-idle: 5 # 最小空闲连接数量 idle-timeout: 180000 # 空闲连接存活最大时间,默认600000(10分钟) maximum-pool-size: 10 # 连接池最大连接数,默认是10 auto-commit: true # 此属性控制从池返回的连接的默认自动提交行为,默认值:true pool-name: MyHikariCP # 连接池名称 max-lifetime: 1800000 # 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟 connection-timeout: 30000 # 数据库连接超时时间,默认30秒,即30000 # connection-test-query: SELECT 1 #连接池每分配一条连接前执行的查询语句(如:SELECT 1),以验证该连接是否是有效的。如果你的驱动程序支持 JDBC4,HikariCP 强烈建议我们不要设置此属性 jpa: hibernate: ddl-auto: update # 第一次建表create 后面用update,要不然每次重启都会新建表 # show-sql: true #打印执行的sql语句 database-platform: org.hibernate.dialect.MySQL5InnoDBDialect #设置数据库方言 记住必须要使用 MySQL5InnoDBDialect 指定数据库类型对应InnoDB ;如果使用MySQLDialect 则对应的是MyISAM test-key: JCccc-test-key-one
OK,这时候我们把项目运行,调用下相关接口:
相关测试的mapper层方法:
@Query(value="select * from user where name=(:name)",nativeQuery = true) User getUserByName(@Param("name") String name);
控制台日志打印情况:
可以看到我们想要的效果已经出来了,但是很多多余的日志都出来了,显然要对这些日志做筛选。
通过日志level级别,进行筛选。
在resources 里新建 logback.xml文件:
具体配置代码(注意注释简述,筛选相关的在最底下):
<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true"> <!-- 从application.yml 中注入变量 --> <!-- <springProperty scope="context" name="LOG_PATH" source="log.home"/> --> <!-- <springProperty scope="context" name="APPDIR" source="spring.application.name"/> --> <property name="LOG_PATH" value="./logs"/> <property name="APPDIR" value="graceLogs"/> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>1-%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger - %msg%n</pattern> <charset>GBK</charset> </encoder> </appender> <!-- error级别日志文件输出,按日期时间滚动记录输出 --> <appender name="FILEERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_PATH}/${APPDIR}/log_error.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_PATH}/${APPDIR}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>500MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <append>true</append> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <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> <!-- warn级别日志文件输出,按日期时间滚动记录输出 --> <appender name="FILEWARN" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_PATH}/${APPDIR}/log_warn.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_PATH}/${APPDIR}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>2MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <append>true</append> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <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> <!-- info级别日志文件输出,按日期时间滚动记录输出 --> <appender name="FILEINFO" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_PATH}/${APPDIR}/log_info.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_PATH}/${APPDIR}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>2MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <append>true</append> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <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="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern> </encoder> </appender> <!--设置为OFF,即屏蔽; 留下sqltiming作为INFO级别输出--> <logger name="jdbc.connection" level="OFF"/> <logger name="jdbc.resultset" level="OFF"/> <logger name="jdbc.resultsettable" level="OFF"/> <logger name="jdbc.audit" level="OFF"/> <logger name="jdbc.sqltiming" level="INFO"/> <logger name="jdbc.sqlonly" level="OFF"/> <!--设置日志打印级别为INFO--> <root level="INFO"> <appender-ref ref="CONSOLE"/> <appender-ref ref="FILEINFO"/> <appender-ref ref="FILEWARN"/> <appender-ref ref="FILEERROR"/> </root> </configuration>
OK,现在重新启动项目,调用接口看看SQL语句和参数打印情况,很好,达到了我们要的效果:
ps:sqltiming和sqlonly差别是多打印了sql语句的耗时,如果不想要这个时间可以修改筛选里面的项。
顺便看看日志文件也输出到了对应的文件夹(这些日志文件会按照日志滚动记录的,现场跑看不出效果):
OK,到此。
PS:
如果是mybatis,如上文一样使用没区别,简单讲下:
1.导入jar
2.改yml配置
3.添加文件
4.可以用了