Spring Boot DATA JPA抓取SQL运行时的传递进去的参数信息

     在系统开发过程中,涉及到数据库操作都是SQL的天下,基于ORM的各类框架来简化开发;在JPA/Hibernate方案中,只提供了SQL的打印输出,但并未输入SQL的参数值是多少,这里将解决这个问题,告知具体如何来实现这个操作。

1.  技术栈的介绍

   JDK 1.8,  Spring Boot 2.0.3.RELEASE, Mysql 5.7

2.  依赖包

    Spring Boot中的JPA依赖包:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-test</artifactId>
	<scope>test</scope>
</dependency>
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
	<groupId>com.googlecode.log4jdbc</groupId>
	<artifactId>log4jdbc</artifactId>
	<version>1.2</version>
</dependency>

3. log4jdbc的介绍

 

    log4jdbc使用SLF4J(Simple Logging Facade For Java)作为日志系统。特性:

  •    支持JDBC3和JDBC4,其中JDBC3对应于JDK 1.4 or 1.5,JDBC4要求JDK 1.6或以上。
  •    支持现有大部分JDBC驱动。
  •   易于配置(在大部分情况下,只需要改变驱动类名并在jdbc url前加上”jdbc:log4“,设置好日志输出级别)。
  •    能够自动把SQL变量值加到SQL输出日志中,改进易读性和方便调试。
  •    能够快速标识出应用程序中执行比较慢的SQL语句。
  •    能够生成SQL连接数信息帮助识别连接池/线程问题。

   综合一句话,log4jdbc可以帮我们实现一个抓取SQL中实际使用值的功能。

4.  Spring Boot示例

     application.properties内容:   

spring.datasource.driver-class-name = net.sf.log4jdbc.DriverSpy
spring.datasource.url= jdbc:log4jdbc:mysql://127.0.0.1:3306/demo?useUnicode=yes&characterEncoding=UTF-8&useSSL=false
spring.datasource.username = root
spring.datasource.password = 123123
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.initialization-mode=never

spring.datasource.hikari.minimum-idle=0
spring.datasource.hikari.idle-timeout=10800000
spring.datasource.hikari.max-lifetime=21600000
spring.datasource.hikari.connection-timeout=6000
spring.datasource.hikari.initialization-fail-timeout=0
spring.datasource.hikari.data-source-properties.useUnicode=true
spring.datasource.hikari.data-source-properties.characterEncoding=utf8
spring.datasource.hikari.data-source-properties.useSSL=false
spring.datasource.hikari.data-source-properties.cachePrepStmts=true
spring.datasource.hikari.data-source-properties.prepStmtCacheSize=512
spring.datasource.hikari.data-source-properties.allowMultiQueries=true
spring.datasource.hikari.data-source-properties.useLocalSessionState=true
spring.datasource.hikari.data-source-properties.prepStmtCacheSqlLimit=81920
spring.datasource.hikari.data-source-properties.rewriteBatchedStatements=false
spring.datasource.hikari.data-source-properties.useOldAliasMetadataBehavior=true
spring.datasource.hikari.data-source-properties.createDatabaseIfNotExist=true

spring.jpa.open-in-view=false
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.hbm2ddl.import_files=data.sql
spring.jpa.show-sql=true

这里需要注意的是mysql的原来的驱动程序.driver-class-name 和mysql的url

spring.datasource.driver-class-name = net.sf.log4jdbc.DriverSpy
spring.datasource.url= jdbc:log4jdbc:mysql://127.0.0.1:3306/demo?useUnicode=yes&characterEncoding=UTF-8&useSSL=false

将被  net.sf.log4jdbc.DriverSpy来替代,可以理解为DriverSpy做为mysql驱动的代理来捕捉SQL的信息。

 

数据库连接的URL需要进行修改为:

   原来的: jdbc:mysql://localhost:3306/mealsystem

   现在的:  jdbc:log4jdbc:mysql://localhost:3306/mealsystem

  除此之外,无需额外的变化需求,其余代码都一致即可获得运行中的SQL信息。

2018-09-04 11:18:52.429  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. Connection.isValid(5) returned true
2018-09-04 11:18:52.429  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. Connection.getAutoCommit() returned true
2018-09-04 11:18:52.429  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. Connection.setAutoCommit(false) returned 
Hibernate: select userpo0_.id as id1_0_0_, userpo0_.address as address2_0_0_, userpo0_.books as books3_0_0_, userpo0_.name as name4_0_0_, userpo0_.phone as phone5_0_0_ from user userpo0_ where userpo0_.id=?
2018-09-04 11:18:52.468  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. PreparedStatement.new PreparedStatement returned 
2018-09-04 11:18:52.468  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. Connection.prepareStatement(select userpo0_.id as id1_0_0_, userpo0_.address as address2_0_0_, userpo0_.books as books3_0_0_, userpo0_.name as name4_0_0_, userpo0_.phone as phone5_0_0_ from user userpo0_ where userpo0_.id=?) returned net.sf.log4jdbc.PreparedStatementSpy@810bf7d
2018-09-04 11:18:52.475  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. PreparedStatement.setInt(1, 1) returned 
2018-09-04 11:18:52.477  INFO 10184 --- [nio-8081-exec-2] jdbc.sqlonly                             : select userpo0_.id as id1_0_0_, userpo0_.address as address2_0_0_, userpo0_.books as books3_0_0_, 
userpo0_.name as name4_0_0_, userpo0_.phone as phone5_0_0_ from user userpo0_ where userpo0_.id=1 

2018-09-04 11:18:52.478  INFO 10184 --- [nio-8081-exec-2] jdbc.sqltiming                           : select userpo0_.id as id1_0_0_, userpo0_.address as address2_0_0_, userpo0_.books as books3_0_0_, 
userpo0_.name as name4_0_0_, userpo0_.phone as phone5_0_0_ from user userpo0_ where userpo0_.id=1 
 {executed in 1 msec}
2018-09-04 11:18:52.481  INFO 10184 --- [nio-8081-exec-2] jdbc.resultset                           : 2. ResultSet.new ResultSet returned 
2018-09-04 11:18:52.481  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. PreparedStatement.executeQuery() returned net.sf.log4jdbc.ResultSetSpy@2bb7b913
2018-09-04 11:18:52.489  INFO 10184 --- [nio-8081-exec-2] jdbc.resultset                           : 2. ResultSet.next() returned true
2018-09-04 11:18:52.498  INFO 10184 --- [nio-8081-exec-2] jdbc.resultset                           : 2. ResultSet.getString(address2_0_0_) returned bj0
2018-09-04 11:18:52.498  INFO 10184 --- [nio-8081-exec-2] jdbc.resultset                           : 2. ResultSet.wasNull() returned false
2018-09-04 11:18:52.498  INFO 10184 --- [nio-8081-exec-2] jdbc.resultset                           : 2. ResultSet.getString(books3_0_0_) returned [{"name": "c++", "price": 53.9}, {"name": "java", "price": 100}]
2018-09-04 11:18:52.498  INFO 10184 --- [nio-8081-exec-2] jdbc.resultset                           : 2. ResultSet.wasNull() returned false
2018-09-04 11:18:52.538  INFO 10184 --- [nio-8081-exec-2] jdbc.resultset                           : 2. ResultSet.getString(name4_0_0_) returned xiaoming
2018-09-04 11:18:52.538  INFO 10184 --- [nio-8081-exec-2] jdbc.resultset                           : 2. ResultSet.wasNull() returned false
2018-09-04 11:18:52.538  INFO 10184 --- [nio-8081-exec-2] jdbc.resultset                           : 2. ResultSet.getString(phone5_0_0_) returned ["15510062270", "15516676760"]
2018-09-04 11:18:52.538  INFO 10184 --- [nio-8081-exec-2] jdbc.resultset                           : 2. ResultSet.wasNull() returned false
2018-09-04 11:18:52.543  INFO 10184 --- [nio-8081-exec-2] jdbc.resultset                           : 2. ResultSet.next() returned false
2018-09-04 11:18:52.575  INFO 10184 --- [nio-8081-exec-2] jdbc.resultset                           : 2. ResultSet.close() returned 
2018-09-04 11:18:52.576  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. PreparedStatement.getMaxRows() returned 0
2018-09-04 11:18:52.576  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. PreparedStatement.getQueryTimeout() returned 0
2018-09-04 11:18:52.576  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. PreparedStatement.close() returned 
Hibernate: update user set address=?, books=?, name=?, phone=? where id=?
2018-09-04 11:18:52.596  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. PreparedStatement.new PreparedStatement returned 
2018-09-04 11:18:52.596  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. Connection.prepareStatement(update user set address=?, books=?, name=?, phone=? where id=?) returned net.sf.log4jdbc.PreparedStatementSpy@741f652
2018-09-04 11:18:52.596  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. PreparedStatement.setString(1, "bj0") returned 
2018-09-04 11:18:52.597  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. PreparedStatement.setString(2, "[{"name":"c++","price":53.9},{"name":"java","price":100.0}]") returned 
2018-09-04 11:18:52.597  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. PreparedStatement.setString(3, "xiaoming") returned 
2018-09-04 11:18:52.597  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. PreparedStatement.setString(4, "["15510062270","15516676760"]") returned 
2018-09-04 11:18:52.597  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. PreparedStatement.setInt(5, 1) returned 
2018-09-04 11:18:52.597  INFO 10184 --- [nio-8081-exec-2] jdbc.sqlonly                             : update user set address='bj0', books='[{"name":"c++","price":53.9},{"name":"java","price":100.0}]', 
name='xiaoming', phone='["15510062270","15516676760"]' where id=1 

2018-09-04 11:18:52.598  INFO 10184 --- [nio-8081-exec-2] jdbc.sqltiming                           : update user set address='bj0', books='[{"name":"c++","price":53.9},{"name":"java","price":100.0}]', 
name='xiaoming', phone='["15510062270","15516676760"]' where id=1 
 {executed in 1 msec}
2018-09-04 11:18:52.598  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. PreparedStatement.executeUpdate() returned 1
2018-09-04 11:18:52.598  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. PreparedStatement.getMaxRows() returned 0
2018-09-04 11:18:52.598  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. PreparedStatement.getQueryTimeout() returned 0
2018-09-04 11:18:52.598  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. PreparedStatement.close() returned 
2018-09-04 11:18:52.605  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. Connection.commit() returned 
2018-09-04 11:18:52.605  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. Connection.setAutoCommit(true) returned 
2018-09-04 11:18:52.607  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. Connection.clearWarnings() returned 
2018-09-04 11:18:52.607  INFO 10184 --- [nio-8081-exec-2] jdbc.audit                               : 2. Connection.clearWarnings() returned 

  可以发现其select和update语句是有具体的值存在的,额外还有执行所使用的时间。

2018-09-04 11:18:52.478  INFO 10184 --- [nio-8081-exec-2] jdbc.sqltiming                           : select userpo0_.id as id1_0_0_, userpo0_.address as address2_0_0_, userpo0_.books as books3_0_0_, 
userpo0_.name as name4_0_0_, userpo0_.phone as phone5_0_0_ from user userpo0_ where userpo0_.id=1 
 {executed in 1 msec}

2018-09-04 11:18:52.598  INFO 10184 --- [nio-8081-exec-2] jdbc.sqltiming                           : update user set address='bj0', books='[{"name":"c++","price":53.9},{"name":"java","price":100.0}]', 
name='xiaoming', phone='["15510062270","15516676760"]' where id=1 
 {executed in 1 msec}

6. 参考资料

  •   http://www.cnblogs.com/xdp-gacl/p/4081848.html
  •  http://my.oschina.net/kzhou/blog/149532
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值