打印hibernate的SQL语句的几种办法

摘要

使用hibernate时,我们常常需要查看hibernate实际提交到数据库的SQL及相关参数。这里提供几种方案,供大家在开发中使用。

使用hibernate-configuration

这也许是最简单的一种配置。我们只需要为hibernate配置一个参数,就可以在console中打印出SQL语句。

需要增加的仅仅是这个参数(其它参数略去):


<hibernate-configuration>

    <session-factory>

        <property name="show_sql">true</property>

    </session-factory>

</hibernate-configuration>

与打印SQL语句相关的配置,还有两个:format_sql和use_sql_comments。顾名思义,他们配置的是打印SQL时是否进行格式化、以及是否打印出相关的注释。

但是,hibernate自己的配置中,似乎不能将参数绑定到SQL上,SQL语句中只有问号占位符。


使用log4j

如果使用log4j,我们需要做的就是为hibernate相应的类配置logger和appender。appender的配置略去(开发中一般就配置为console),logger配置如下:


# log4j.properties文件的配置

log4j.logger.org.hibernate.SQL=DEBUG

log4j.logger.org.hibernate.type=TRACE


# log4j.xml文件的配置

<Logger name="org.hibernate.SQL" level="DEBUG"></Logger>

<Logger name="org.hibernate.type" level="TRACE"></Logger>

上面的配置中,org.hibernate.SQL的日志配置的效果与show_sql=true的配置果相似,都会把SQL语句打印出来。而org.hibernate.type的日志配置,则会把SQL中占位符对应的参数打印出来。两者结合起来,日志结果如下:

Hibernate: INSERT INTO mkyong.stock_transaction (CHANGE, CLOSE, DATE, OPEN, STOCK_ID, VOLUME)VALUES (?, ?, ?, ?, ?, ?)13:33:07,253 DEBUG FloatType:133 - binding ‘10.0‘ to parameter: 1
13:33:07,253 DEBUG FloatType:133 - binding ‘1.1‘ to parameter: 2
13:33:07,253 DEBUG DateType:133 - binding ‘30 December 2009‘ to parameter: 3
13:33:07,269 DEBUG FloatType:133 - binding ‘1.2‘ to parameter: 4
13:33:07,269 DEBUG IntegerType:133 - binding ‘11‘ to parameter: 5
13:33:07,269 DEBUG LongType:133 - binding ‘1000000‘ to parameter: 6

但是,尽管这种方式能够把SQL和参数都打印出来,但是二者却是分开打印的。如果一段时间内执行的SQL非常多,那么这部分日志会比较的杂乱,对于开发来说帮助并不大。


使用p6spy

P6Spy是一个可以用来在应用程序中拦截和修改数据操作语句的开源框架。 通过P6Spy我们可以对SQL语句进行拦截,相当于一个SQL语句的记录器。使用P6spy,我们需要的配置比较复杂,清单如下。

绝对不要把这些配置提交到上线代码中!

首先,我们需要引入相关jar包。

pom.xml


<!-- https://mvnrepository.com/artifact/p6spy/p6spy -->

<dependency>

    <groupId>p6spy</groupId>

    <artifactId>p6spy</artifactId>

    <version>3.0.0</version>

</dependency>

第二,我们需要“处理”一下数据源配置。

spring-db.xml


<bean id="dataSource" class="com.p6spy.engine.spy.P6DataSource">

    <constructor-arg>

        <bean class="com.mchange.v2.c3p0.ComboPooledDataSource"

            destroy-method="close">

            <property name="driverClass" value="org.h2.Driver" />

            <property name="jdbcUrl"

                value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;IGNORECASE=TRUE;MODE=MySQL;MVCC=true" />

            <property name="user" value="sa" />

            <property name="password" value="" />

        </bean>

    </constructor-arg>

</bean>

最后,我们需要为p6spy增加一个配置文件,放到resource路径下。其中可配置项很多,我们可以只配置一部分(例如示例中的三项)。完整配置可以查看他们的官网。

p6spy.properties


# 默认会在项目路径下创建spy.log

logfile = C:/Users/Administrator/Desktop/log/spy.log

# 默认apptend=true,会导致日志文件不断扩大

append=false

# 默认是dd-MMM-yy

databaseDialectDateFormat=yyyy-MM-dd

配置好之后,spy.log中应该会有这样的输出。红色字体部分就是带有参数的SQL语句。

1485070310889|0|statement|connection 10|select companyacc0_.id as id1_24_, companyacc0_.balance as balance2_24_, companyacc0_.lastUpdateTime as lastUpda3_24_, companyacc0_.type as type4_24_ from company_accounts companyacc0_ where companyacc0_.type=?|select companyacc0_.id as id1_24_, companyacc0_.balance as balance2_24_, companyacc0_.lastUpdateTime as lastUpda3_24_, companyacc0_.type as type4_24_ from company_accounts companyacc0_ where companyacc0_.type=‘MAIN‘


参考

使用hibernate的show_sql方式配置:http://www.mkyong.com/hibernate/hibernate-display-generated-sql-to-console-show_sql-format_sql-and-use_sql_comments/

使用Log4j配置:http://www.mkyong.com/hibernate/how-to-display-hibernate-sql-parameter-values-log4j/

使用P6spy配置:http://www.mkyong.com/hibernate/how-to-display-hibernate-sql-parameter-values-solution/

P6spy官方配置说明:http://p6spy.readthedocs.io/en/latest/configandusage.html

时间: 2024-08-03 17:19:58

打印hibernate的SQL语句的几种办法的相关文章

在hibernate中用sql语句

在hibernate中用sql语句,语句是createSQLquery 查出来的是,一列或者多列的数据,要将其转化为对象,有两种方式, 对于已经被hibernate所管理的实体类,在后面加.addentity 然后用花括号在sql语句中,select之后from之前,每一个{表名.*},就可以查询出对象. 对于数据传输的dto类,用setresulttransformer.然后在select之后 from之前,把列名和dto的属性名一一as起来. 百万级的数据存储,用外键关联会降低效率 可以选择

MyBatis插件及示例----打印每条SQL语句及其执行时间

Plugins 摘一段来自MyBatis官方文档的文字. MyBatis允许你在某一点拦截已映射语句执行的调用.默认情况下,MyBatis允许使用插件来拦截方法调用 Executor(update.query.flushStatements.commint.rollback.getTransaction.close.isClosed) ParameterHandler(getParameterObject.setParameters) ResultSetHandler(handleResultS

log4j打印MyBatis的sql语句配置

log4j.rootLogger=DEBUG,stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) -%m%n log4j.logger.com.ibatis=debug log4j

MyBatis7:MyBatis插件及示例----打印每条SQL语句及其执行时间

Plugins 摘一段来自MyBatis官方文档的文字. MyBatis允许你在某一点拦截已映射语句执行的调用.默认情况下,MyBatis允许使用插件来拦截方法调用 Executor(update.query.flushStatements.commint.rollback.getTransaction.close.isClosed) ParameterHandler(getParameterObject.setParameters) ResultSetHandler(handleResultS

采用p6spy完整显示hibernate的SQL语句

虽然在hibernate中有show_sql选项,但是显示出来的语句大多类似 select * from xxx where value=? 但是有时候我们需要得到完整的SQL语句,怎么办呢?使用P6SPY就可以完成这个任务 p6spy是一个开源软件,它可以跟踪任何使用jdbc的应用产生的数据库操作.特别适合于监控ejb服务器产生的 sql statements.官方网址:http://www.p6spy.com/目前p6spy 适用的应用服务器包括jboss, atg, orion, jona

PDO中执行SQL语句的三种方法

在PDO中,我们可以使用三种方式来执行SQL语句,分别是 exec()方法,query方法,以及预处理语句prepare()和execute()方法~大理石构件来图加工 在上一篇文章<使用PDO构造函数连接数据库及DSN详解>中,我们介绍了如何使用构造函数连接数据库和DSN的详解,那么我们这篇文章跟大家介绍在PDO中执行SQL语句的三种方式,下面我们将一一介绍! 第一种方法:exec()方法 exec()方法返回执行SQL 语句后受影响的行数,其语法格式如下: 1 int PDO::exec(

Hibernate 执行sql语句返回yntax error: syntax error, expect LPAREN, actual NOT not

hibernate自动创建表时提示 :  ERROR: sql injection violation, syntax error: syntax error, expect LPAREN, actual NOT not : 可是我把sql语句在sql客户端执行是Ok的 后来在一个博客的评论区找到了原因 原来改sql语句执行被druid配置的防火墙拦截了 将druid.filters属性中的wall去掉就好

C#中产生SQL语句的几种方式

(1)拼接产生SQL语句: string sql = "insert into czyb(yhm,mm,qx) values('" + txtName.Text + "','" + txtPassword.Text + "','" + cmbPriority.Text + "')";       OleDbCommand cmd = new OleDbCommand(sql, conn); 这种方法写法比较复杂,且安全性低,容

Ibatis 后台打印完整的sql语句

http://blog.csdn.net/deng11342/article/details/9122015 http://www.blogjava.net/libin2722/archive/2007/12/04/165153.html 打印Ibatis最终的SQL语句 在项目开发时都大家都希望将SQL在后台打印出来,以帮助开发以及后续的bug修改.如果用JDBC那么可以方便的打印,可使用ibatis就不知道怎么办了,最近在网上找了一段log4j的配置可以很保姆的处理这个问题.这里贴出来给大家