【p6spy】程序员开发利器P6spy——打印执行sql语句,mybatis、ibatis、Hibernate均可使用

深藏阁楼爱情的钟 2022-06-03 00:00 1255阅读 0赞

一、前言

  1. 在开发的过程中,总希望方法执行完了可以看到完整是sql语句,从而判断执行的是否正确,所以就希望有一个可以打印sql语句的插件。p6spy就是一款针对数据库访问操作的动态监控框架,他可以和数据库无缝截取和操纵,而不必对现有应该用程序的代码做任何修改。
  2. 通过p6spy可以直接打印数据库执行的语句,下面向大家介绍一下p6spy

二、使用p6spy,需要什么?

  • p6spy的jar包
  • spy.properties
  • 自定义日志格式
  • 修改相关配置文件

三、使用过程

3.1 添加p6spy的依赖

  1. <!--打印数据库SQL语句-->
  2. <dependency>
  3. <groupId>p6spy</groupId>
  4. <artifactId>p6spy</artifactId>
  5. <version>3.6.0</version>
  6. </dependency>

3.2 修改Dao相关配置文件

  1. 在连接数据源的配置文件中,添加p6spy连接设置:
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">
  4. <!--p6spy连接设置-->
  5. <bean id="dataSource" class="com.p6spy.engine.spy.P6DataSource">
  6. <constructor-arg>
  7. <ref bean="dataSourceDefault"/>
  8. </constructor-arg>
  9. </bean>
  10. <!-- 数据库连接池 -->
  11. <!-- 加载配置文件 -->
  12. <context:property-placeholder location="classpath:conf/db.properties" />
  13. <!-- 数据库连接池 -->
  14. <bean id="dataSourceDefault" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
  15. <!-- 基本属性 url username password driverClassName-->
  16. <property name="url" value="${jdbc.url}" />
  17. <property name="username" value="${jdbc.username}" />
  18. <property name="password" value="${jdbc.password}" />
  19. <!--<property name="driverClassName" value="${jdbc.driver}" />-->
  20. <!--配置初始化大小、最小、最多连接数-->
  21. <property name="initialSize" value="1"/>
  22. <property name="maxActive" value="100" />
  23. <property name="minIdle" value="5" />
  24. <!--配置获取连接等待超时时间-->
  25. <property name="maxWait" value="3000"/>
  26. <!--配置间隔多久进行一次检测,检测需要关闭的空闲连接,单位是毫秒-->
  27. <property name="timeBetweenEvictionRunsMillis" value="6000"/>
  28. <!--配置一个连接在连接池中,最小生存的时间,单位是毫秒-->
  29. <property name="minEvictableIdleTimeMillis" value="30000"/>
  30. <property name="validationQuery" value="SELECT 'x'" />
  31. <property name="testWhileIdle" value="true" />
  32. <property name="testOnBorrow" value="false" />
  33. <property name="testOnReturn" value="false" />
  34. <!--打开PSCache,并且指定每个连接上的PSCache的大小-->
  35. <property name="poolPreparedStatements" value="true"/>
  36. <property name="maxPoolPreparedStatementPerConnectionSize" value="20"/>
  37. <!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计 -->
  38. <property name="filters" value="stat" />
  39. </bean>
  40. <!-- spring管理sqlsessionfactory 使用mybatisspring整合包中的 -->
  41. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  42. <!-- 数据库连接池 -->
  43. <property name="dataSource" ref="dataSource" />
  44. <!-- 加载mybatis的全局配置文件 -->
  45. <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml" />
  46. </bean>
  47. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  48. <property name="basePackage" value="com.dmsd.dao" />
  49. </bean>
  50. </beans>

3.2 添加spy.properties

  1. 文件内容如下:
  2. ###
  3. # #%L
  4. # P6Spy
  5. # %%
  6. # Copyright (C) 2013 P6Spy
  7. # %%
  8. # Licensed under the Apache License, Version 2.0 (the "License");
  9. # you may not use this file except in compliance with the License.
  10. # You may obtain a copy of the License at
  11. #
  12. # http://www.apache.org/licenses/LICENSE-2.0
  13. #
  14. # Unless required by applicable law or agreed to in writing, software
  15. # distributed under the License is distributed on an "AS IS" BASIS,
  16. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. # See the License for the specific language governing permissions and
  18. # limitations under the License.
  19. # #L%
  20. ###
  21. #################################################################
  22. # P6Spy Options File #
  23. # See documentation for detailed instructions #
  24. # http://p6spy.github.io/p6spy/2.0/configandusage.html #
  25. #################################################################
  26. #################################################################
  27. # MODULES #
  28. # #
  29. # Module list adapts the modular functionality of P6Spy. #
  30. # Only modules listed are active. #
  31. # (default is com.p6spy.engine.logging.P6LogFactory and #
  32. # com.p6spy.engine.spy.P6SpyFactory) #
  33. # Please note that the core module (P6SpyFactory) can't be #
  34. # deactivated. #
  35. # Unlike the other properties, activation of the changes on #
  36. # this one requires reload. #
  37. #################################################################
  38. #modulelist=com.p6spy.engine.spy.P6SpyFactory,com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
  39. ################################################################
  40. # CORE (P6SPY) PROPERTIES #
  41. ################################################################
  42. # A comma separated list of JDBC drivers to load and register.
  43. # (default is empty)
  44. #
  45. # Note: This is normally only needed when using P6Spy in an
  46. # application server environment with a JNDI data source or when
  47. # using a JDBC driver that does not implement the JDBC 4.0 API
  48. # (specifically automatic registration).
  49. #driverlist=
  50. driverlist=com.mysql.jdbc.Driver
  51. # for flushing per statement
  52. # (default is false)
  53. #autoflush = false
  54. # sets the date format using Java's SimpleDateFormat routine.
  55. # In case property is not set, miliseconds since 1.1.1970 (unix time) is used (default is empty)
  56. #dateformat=
  57. # prints a stack trace for every statement logged
  58. #stacktrace=false
  59. # if stacktrace=true, specifies the stack trace to print
  60. #stacktraceclass=
  61. # determines if property file should be reloaded
  62. # Please note: reload means forgetting all the previously set
  63. # settings (even those set during runtime - via JMX)
  64. # and starting with the clean table
  65. # (default is false)
  66. #reloadproperties=false
  67. reloadproperties=true
  68. # determines how often should be reloaded in seconds
  69. # (default is 60)
  70. #reloadpropertiesinterval=60
  71. # specifies the appender to use for logging
  72. # Please note: reload means forgetting all the previously set
  73. # settings (even those set during runtime - via JMX)
  74. # and starting with the clean table
  75. # (only the properties read from the configuration file)
  76. # (default is com.p6spy.engine.spy.appender.FileLogger)
  77. #appender=com.p6spy.engine.spy.appender.Slf4JLogger
  78. #appender=com.p6spy.engine.spy.appender.StdoutLogger
  79. #appender=com.p6spy.engine.spy.appender.FileLogger
  80. appender=com.p6spy.engine.spy.appender.Slf4JLogger
  81. # name of logfile to use, note Windows users should make sure to use forward slashes in their pathname (e:/test/spy.log)
  82. # (used for com.p6spy.engine.spy.appender.FileLogger only)
  83. # (default is spy.log)
  84. #logfile = spy.log
  85. # append to the p6spy log file. if this is set to false the
  86. # log file is truncated every time. (file logger only)
  87. # (default is true)
  88. #append=true
  89. # class to use for formatting log messages (default is: com.p6spy.engine.spy.appender.SingleLineFormat)
  90. #logMessageFormat=com.p6spy.engine.spy.appender.SingleLineFormat
  91. #自定义日志格式,在类中定义
  92. logMessageFormat= com.dmsd.tool.P6SpyLogger
  93. # format that is used for logging of the date/time/... (has to be compatible with java.text.SimpleDateFormat)
  94. # (default is dd-MMM-yy)
  95. #databaseDialectDateFormat=dd-MMM-yy
  96. databaseDialectDateFormat=yyyy-MM-dd HH:mm:ss
  97. # whether to expose options via JMX or not
  98. # (default is true)
  99. #jmx=true
  100. # if exposing options via jmx (see option: jmx), what should be the prefix used?
  101. # jmx naming pattern constructed is: com.p6spy(.<jmxPrefix>)?:name=<optionsClassName>
  102. # please note, if there is already such a name in use it would be unregistered first (the last registered wins)
  103. # (default is none)
  104. #jmxPrefix=
  105. #################################################################
  106. # DataSource replacement #
  107. # #
  108. # Replace the real DataSource class in your application server #
  109. # configuration with the name com.p6spy.engine.spy.P6DataSource #
  110. # (that provides also connection pooling and xa support). #
  111. # then add the JNDI name and class name of the real #
  112. # DataSource here #
  113. # #
  114. # Values set in this item cannot be reloaded using the #
  115. # reloadproperties variable. Once it is loaded, it remains #
  116. # in memory until the application is restarted. #
  117. # #
  118. #################################################################
  119. #realdatasource=/RealMySqlDS
  120. #realdatasourceclass=com.mysql.jdbc.jdbc2.optional.MysqlDataSource
  121. #################################################################
  122. # DataSource properties #
  123. # #
  124. # If you are using the DataSource support to intercept calls #
  125. # to a DataSource that requires properties for proper setup, #
  126. # define those properties here. Use name value pairs, separate #
  127. # the name and value with a semicolon, and separate the #
  128. # pairs with commas. #
  129. # #
  130. # The example shown here is for mysql #
  131. # #
  132. #################################################################
  133. #realdatasourceproperties=port;3306,serverName;myhost,databaseName;jbossdb,foo;bar
  134. #################################################################
  135. # JNDI DataSource lookup #
  136. # #
  137. # If you are using the DataSource support outside of an app #
  138. # server, you will probably need to define the JNDI Context #
  139. # environment. #
  140. # #
  141. # If the P6Spy code will be executing inside an app server then #
  142. # do not use these properties, and the DataSource lookup will #
  143. # use the naming context defined by the app server. #
  144. # #
  145. # The two standard elements of the naming environment are #
  146. # jndicontextfactory and jndicontextproviderurl. If you need #
  147. # additional elements, use the jndicontextcustom property. #
  148. # You can define multiple properties in jndicontextcustom, #
  149. # in name value pairs. Separate the name and value with a #
  150. # semicolon, and separate the pairs with commas. #
  151. # #
  152. # The example shown here is for a standalone program running on #
  153. # a machine that is also running JBoss, so the JDNI context #
  154. # is configured for JBoss (3.0.4). #
  155. # #
  156. # (by default all these are empty) #
  157. #################################################################
  158. #jndicontextfactory=org.jnp.interfaces.NamingContextFactory
  159. #jndicontextproviderurl=localhost:1099
  160. #jndicontextcustom=java.naming.factory.url.pkgs;org.jboss.nameing:org.jnp.interfaces
  161. #jndicontextfactory=com.ibm.websphere.naming.WsnInitialContextFactory
  162. #jndicontextproviderurl=iiop://localhost:900
  163. ################################################################
  164. # P6 LOGGING SPECIFIC PROPERTIES #
  165. ################################################################
  166. # filter what is logged
  167. # please note this is a precondition for usage of: include/exclude/sqlexpression
  168. # (default is false)
  169. #filter=false
  170. # comma separated list of strings to include
  171. # please note that special characters escaping (used in java) has to be done for the provided regular expression
  172. # (default is empty)
  173. #include =
  174. # comma separated list of strings to exclude
  175. # (default is empty)
  176. #exclude =
  177. # sql expression to evaluate if using regex
  178. # please note that special characters escaping (used in java) has to be done for the provided regular expression
  179. # (default is empty)
  180. #sqlexpression =
  181. #list of categories to exclude: error, info, batch, debug, statement,
  182. #commit, rollback and result are valid values
  183. # (default is info,debug,result,resultset,batch)
  184. #excludecategories=info,debug,result,resultset,batch
  185. excludecategories=info,debug,result,resultset
  186. # Execution threshold applies to the standard logging of P6Spy.
  187. # While the standard logging logs out every statement
  188. # regardless of its execution time, this feature puts a time
  189. # condition on that logging. Only statements that have taken
  190. # longer than the time specified (in milliseconds) will be
  191. # logged. This way it is possible to see only statements that
  192. # have exceeded some high water mark.
  193. # This time is reloadable.
  194. #
  195. # executionThreshold=integer time (milliseconds)
  196. # (default is 0)
  197. #executionThreshold=
  198. ################################################################
  199. # P6 OUTAGE SPECIFIC PROPERTIES #
  200. ################################################################
  201. # Outage Detection
  202. #
  203. # This feature detects long-running statements that may be indicative of
  204. # a database outage problem. If this feature is turned on, it will log any
  205. # statement that surpasses the configurable time boundary during its execution.
  206. # When this feature is enabled, no other statements are logged except the long
  207. # running statements. The interval property is the boundary time set in seconds.
  208. # For example, if this is set to 2, then any statement requiring at least 2
  209. # seconds will be logged. Note that the same statement will continue to be logged
  210. # for as long as it executes. So if the interval is set to 2, and the query takes
  211. # 11 seconds, it will be logged 5 times (at the 2, 4, 6, 8, 10 second intervals).
  212. #
  213. # outagedetection=true|false
  214. # outagedetectioninterval=integer time (seconds)
  215. #
  216. # (default is false)
  217. #outagedetection=false
  218. # (default is 60)
  219. #outagedetectioninterval=30
  220. 注意:
  221. 在文档中,自定义日志格式,`logMessageFormat= com.dmsd.tool.P6SpyLogger`,在类中定义,指明了路径,在跳转第三步,需要自己定义。

3.3 创建P6SpyLogger类,自定义日志格式

  1. 因为这个都会使用,所以就定义在了tool工具类里:
  2. package com.dmsd.tool;
  3. import com.p6spy.engine.spy.appender.MessageFormattingStrategy;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Date;
  6. public class P6SpyLogger implements MessageFormattingStrategy {
  7. private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
  8. public P6SpyLogger() {
  9. }
  10. @Override
  11. public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql) {
  12. return !"".equals(sql.trim())?this.format.format(new Date()) + " | took " + elapsed + "ms | " + category + " | connection " + connectionId + "\n " + sql + ";":"";
  13. }
  14. }

3.5 运行结果对比

  1. 没有使用:什么都没有,看的不清晰。

这里写图片描述

  1. 使用之后:

这里写图片描述

四、小结

  1. 通过测试使用,提高了自己的代码能力,也从一定方向上,提升了思考问题的能力。有的时候就需要我们用工具去解决问题,程序员的创造力是无穷的。

发表评论

表情:
评论列表 (有 0 条评论,1255人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Mybatis 配置p6spy

    在开发中,为了更方便的知道编写的sql语句是否正确,则通过配置p6spy在控制台打印sql语句,从而解决因sql语句错误导致的程序运行失败,配置方式如下: 1,导入p6sp

    相关 使用P6Spy格式化SQL语句

    公司最近在做一个项目,开发过程中遇到点小问题,查询结果出不来,查看自带日志打印,有点不爽,特别是想复制sql语句到数据库navicat中去调试时,还要手动复制参数值,很是麻烦,

    相关 P6Spy

     P6Spy是一个可以用来在应用程序中拦截和修改数据操作语句的开源框架。通过P6Spy我们可以对SQL语句进行拦截,相当于一个SQL语句的记录器,这样我们可以用它来作相关的分析