Springboot JPA日志输出打印SQL语句和传入的参数 高阶篇
如果仅仅想看到sql语句和参数就完事了,可以参考这篇就足矣:
https://blog.csdn.net/qq_35387940/article/details/102561244
这篇里面我们最终要实现的效果是:
日志里面直接输出的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.可以用了