在Hibernate中是否有可能用真实值而不是问号打印生成的SQL查询?
如果无法使用Hibernate API,您会建议如何使用实际值打印查询?
在Hibernate中是否有可能用真实值而不是问号打印生成的SQL查询?
如果无法使用Hibernate API,您会建议如何使用实际值打印查询?
当前回答
如果您使用Spring Boot 3和/或Hibernate 6,以下配置将显示参数值:
# basic log level for all messages
logging.level.org.hibernate=info
# SQL statements and parameters
logging.level.org.hibernate.SQL=debug
logging.level.org.hibernate.orm.jdbc.bind=trace
# Statistics and slow queries
logging.level.org.hibernate.stat=debug
logging.level.org.hibernate.SQL_SLOW=info
# 2nd Level Cache
logging.level.org.hibernate.cache=debug
其他回答
打开org.hibernate.type记录器,查看实际参数是如何绑定到问号的。
日志可以工作,但并不是您想要的,但P6Spy可以完美地工作。
这里有一个简单的教程来实现以及。对我来说,这就像魅力。
下载P6Spy库:获取P6Spy -install.jar 解压:解压p6spy-install.jar文件,查找p6spy.jar和spy.properties 添加库依赖项:将p6spy.jar添加到项目库依赖项中 Modify P6Spy properties file:修改数据库配置文件。您需要用P6Spy JDBC驱动程序替换现有的JDBC驱动程序。
原来是MySQL JDBC驱动程序- (com.mysql.jdbc.Driver)
<session-factory>
<property name="hibernate.bytecode.use_reflection_optimizer">false</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <!-- note the difference -->
<property name="hibernate.connection.password">password</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/myuser</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
</session-factory>
更改为P6Spy JDBC驱动程序(com.p6spy.engine.spy.P6SpyDriver)
<session-factory>
<property name="hibernate.bytecode.use_reflection_optimizer">false</property>
<property name="hibernate.connection.driver_class">com.p6spy.engine.spy.P6SpyDriver</property> <!-- note the difference -->
<property name="hibernate.connection.password">password</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/myuser</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
</session-factory>
修改P6Spy属性文件:spy.properties
用现有的MySQL JDBC驱动程序替换realdriver
realdriver=com.mysql.jdbc.Driver
# specifies another driver to use
realdriver2=
# specifies a third driver to use
realdriver3=
在logfile属性中更改日志文件的位置。所有SQL语句都将被记录到这个文件中。
窗口:
logfile=c:/spy.log
UNIX:
logfile=/srv/log/spy.log
复制的间谍。属性到项目类路径:复制间谍。属性添加到项目根文件夹。确保你的项目可以定位间谍。财产,否则就是间谍。属性文件未找到异常将被抛出。
解决方案是正确的,但也记录结果对象的所有绑定。为了防止这种情况,可以创建一个单独的追加器并启用过滤。例如:
<!-- A time/date based rolling appender -->
<appender name="FILE_HIBERNATE" class="org.jboss.logging.appender.DailyRollingFileAppender">
<errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
<param name="File" value="${jboss.server.log.dir}/hiber.log"/>
<param name="Append" value="false"/>
<param name="Threshold" value="TRACE"/>
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
</layout>
<filter class="org.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="bind" />
<param name="AcceptOnMatch" value="true" />
</filter>
<filter class="org.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="select" />
<param name="AcceptOnMatch" value="true" />
</filter>
<filter class="org.apache.log4j.varia.DenyAllFilter"/>
</appender>
<category name="org.hibernate.type">
<priority value="TRACE"/>
</category>
<logger name="org.hibernate.type">
<level value="TRACE"/>
<appender-ref ref="FILE_HIBERNATE"/>
</logger>
<logger name="org.hibernate.SQL">
<level value="TRACE"/>
<appender-ref ref="FILE_HIBERNATE"/>
</logger>
这里的所有答案都很有帮助,但是如果您使用Spring应用程序上下文XML来设置会话工厂,那么设置log4j SQL级别变量只是完成了一部分工作,您还必须设置hibernate。show_sql变量在应用程序上下文中本身来让Hibernate开始实际显示这些值。
中有:
<property name="hibernateProperties">
<value>
hibernate.jdbc.batch_size=25
... <!-- Other parameter values here -->
hibernate.show_sql=true
</value>
</property>
您的log4j文件需要
log4j.logger.org.hibernate.SQL=DEBUG
MySQL JDBC驱动程序已经提供了一个方便的特性来满足这个需求。您必须至少拥有大于或等于5.1.6的JAR版本(例如mysql-connect-jar-5.1.6.jar)。
配置jdbc。添加日志记录器和自定义日志记录器的Url: jdbc.url = jdbc: mysql: / /主持人:港口/ your_db ?记录器= com.mysql.jdbc.log.Slf4JLogger&profileSQL = true&profilerEventHandler = com.xxx.CustomLoggingProfilerEventHandler
它使用slf4j日志记录,如果你的默认日志记录是log4j,你必须添加slf4j-api和slf4j-log4j12作为依赖项来使用slf4j日志记录:
Write your custom logging code: package com.xxx; import java.sql.SQLException; import java.util.Properties; import com.mysql.jdbc.Connection; import com.mysql.jdbc.log.Log; public class CustomLoggingProfilerEventHandler implements ProfilerEventHandler { private Log log; public LoggingProfilerEventHandler() { } public void consumeEvent(ProfilerEvent evt) { /** * you can only print the sql as his.log.logInfo(evt.getMessage()) * you can adjust your sql print log level with: DEBUG,INFO * you can also handle the message to meet your requirement */ this.log.logInfo(evt); } public void destroy() { this.log = null; } public void init(Connection conn, Properties props) throws SQLException { this.log = conn.getLog(); } }