在进行开发时,偶尔会想知道自己的查询结果是什么,参数有没有传错,
对于原生语句,下面一个简单的getOne查询,控制台的输出是这样的
这样子对我来说,当我想知道id究竟传进入什么值,获得得到的结果集是怎么样的,就显得比较难受
select user0_.id as id1_1_0_, user0_.age as age2_1_0_, user0_.dept_id as dept_id4_1_0_, user0_.user_name as user_nam3_1_0_, dept1_.id as id1_0_1_, dept1_.dept_name as dept_nam2_0_1_ from sys_user user0_ left outer join sys_dept dept1_ on user0_.dept_id=dept1_.id where user0_.id=?
为了解决上面问题,我引入了log4jdbc框架
<dependency>
<groupId>org.bgee.log4jdbc-log4j2</groupId>
<artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
<version>1.16</version>
</dependency>
spring:
datasource:
# 这里在jdbc与mysql之间加入log4jdbc,注意冒号
url: jdbc:log4jdbc:mysql://localhost:3306/jpa?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
username: root
password: 123456
# 驱动需要进行修改
driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
## 原配置
#spring:
# datasource:
# url: jdbc:mysql://localhost:3306/jpa?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
# username: root
# password: 123456
# driver-class-name: com.mysql.cj.jdbc.Driver
在resources目录下,新建log4jdbc.log4j2.properties属性文件,添加以下配置
# 这里采用slf4j日志
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
# 将自动设置驱动关闭
log4jdbc.auto.load.popular.drivers=false
# 设置mysql驱动
log4jdbc.drivers=com.mysql.cj.jdbc.Driver
这一步,不是必须,只是个人的配置而已
<configuration scan="true" scanPeriod="60 seconds"
debug="false">
<contextName>jpa-select-jpacontextName>
<property name="log.path" value="logs/"/>
<conversionRule conversionWord="clr"
converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex"
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<appender name="CONSOLE"
class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debuglevel>
filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}Pattern>
<charset>UTF-8charset>
encoder>
appender>
<appender name="DEBUG_FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/web_debug.logfile>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} -
%msg%n
pattern>
<charset>UTF-8charset>
encoder>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/web-debug-%d{yyyy-MM-dd}.%i.log
fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MBmaxFileSize>
timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>15maxHistory>
rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>debuglevel>
<onMatch>ACCEPTonMatch>
<onMismatch>DENYonMismatch>
filter>
appender>
<appender name="INFO_FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/web_info.logfile>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} -
%msg%n
pattern>
<charset>UTF-8charset>
encoder>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/web-info-%d{yyyy-MM-dd}.%i.log
fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MBmaxFileSize>
timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>15maxHistory>
rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>infolevel>
<onMatch>ACCEPTonMatch>
<onMismatch>DENYonMismatch>
filter>
appender>
<appender name="WARN_FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/web_warn.logfile>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} -
%msg%n
pattern>
<charset>UTF-8charset>
encoder>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/web-warn-%d{yyyy-MM-dd}.%i.log
fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MBmaxFileSize>
timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>15maxHistory>
rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warnlevel>
<onMatch>ACCEPTonMatch>
<onMismatch>DENYonMismatch>
filter>
appender>
<appender name="ERROR_FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/web_error.logfile>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} -
%msg%n
pattern>
<charset>UTF-8charset>
encoder>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/web-error-%d{yyyy-MM-dd}.%i.log
fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MBmaxFileSize>
timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>15maxHistory>
rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERRORlevel>
<onMatch>ACCEPTonMatch>
<onMismatch>DENYonMismatch>
filter>
appender>
<logger name="jdbc.sqlonly" level="INFO" additivity="false">
<appender-ref ref="CONSOLE"/>
logger>
<logger name="jdbc.resultsettable" level="INFO" additivity="false">
<appender-ref ref="CONSOLE"/>
logger>
<logger name="jdbc.resultset" level="OFF" additivity="false">
<appender-ref ref="CONSOLE">appender-ref>
logger>
<logger name="jdbc.audit" level="OFF" additivity="false">
<appender-ref ref="CONSOLE"/>
logger>
<logger name="jdbc.connection" level="OFF" additivity="false">
<appender-ref ref="CONSOLE"/>
logger>
<logger name="jdbc.sqltiming" level="OFF" additivity="false">
<appender-ref ref="CONSOLE"/>
logger>
<springProfile name="dev">
<root level="info">
<appender-ref ref="CONSOLE"/>
root>
springProfile>
<springProfile name="pro">
<root level="info">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="DEBUG_FILE"/>
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="WARN_FILE"/>
<appender-ref ref="ERROR_FILE"/>
root>
springProfile>
configuration>
重新运行同一个查询语句后,我们惊喜的发现,打印出来的sql语句后面有我们传进入的参数值,同时还给打印出结果集。这下就舒服多了!
2020-02-29 23:15:57.895 INFO 25016 --- [ main] jdbc.sqlonly : select user0_.id as id1_1_0_, user0_.age as age2_1_0_, user0_.dept_id as dept_id4_1_0_, user0_.user_name
as user_nam3_1_0_, dept1_.id as id1_0_1_, dept1_.dept_name as dept_nam2_0_1_ from sys_user
user0_ left outer join sys_dept dept1_ on user0_.dept_id=dept1_.id where user0_.id=1
2020-02-29 23:15:57.925 INFO 25016 --- [ main] jdbc.resultsettable :
|---------|----|--------|----------|---|----------|
|id |age |dept_id |user_name |id |dept_name |
|---------|----|--------|----------|---|----------|
|[unread] |21 |1 |张三 |1 |财务部 |
|---------|----|--------|----------|---|----------|