如何查看JPA发出的SQL查询?

问题描述 投票:138回答:13

当我的代码发出这样的调用时:

entityManager.find(Customer.class, customerID);

如何查看此调用的SQL查询?假设我没有访问数据库服务器来分析/监控调用,是否可以在我的IDE中记录或查看JPA调用发出的相应SQL查询?我使用jTDS驱动程序反对SQL Server 2008 R2。

java jpa
13个回答
316
投票

日志选项是特定于提供程序的。您需要知道您使用哪个JPA实现。

  • Hibernate(see here): <property name = "hibernate.show_sql" value = "true" />
  • EclipseLink(see here): <property name="eclipselink.logging.level" value="FINE"/>
  • OpenJPA(see here): <property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/>
  • DataNucleus(see here): 将日志类别DataNucleus.Datastore.Native设置为一个级别,如DEBUG


0
投票

另一个good option,如果你有太多的日志,你想只作为一个时间System.out.println(),你可以,根据你的提供商做:

CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
CriteriaQuery<ExaminationType> criteriaQuery = criteriaBuilder.createQuery(getEntityClass()); 

/* For Hibernate */
System.out.println(getEntityManager().createQuery(criteriaQuery).unwrap(org.hibernate.Query.class).getQueryString());

/* For OpenJPA */ 
System.out.println(getEntityManager().createQuery(criteriaQuery).unwrap(org.apache.openjpa.persistence.QueryImpl.class).getQueryString());

/* For EclipseLink */
System.out.println(getEntityManager().createQuery(criteriaQuery).unwrap(JpaQuery.class).getSQLString());

0
投票

使用Spring Boot,只需在application.properties中添加:spring.jpa.show-sql = true。这将显示查询但没有实际参数(您将看到?而不是每个参数)。


-1
投票

有一个名为persistence.xml的文件按Ctrl + Shift + R然后找到它,然后,有一个类似showSQL的地方。

说实话吧

我不确定服务器是否必须作为调试模式启动。检查在控制台上创建的SQL。


34
投票

此外,如果您正在使用EclipseLink并希望输出SQL参数值,则可以将此属性添加到persistence.xml文件中:

<property name="eclipselink.logging.parameters" value="true"/>

15
投票

如果您使用hibernate和logback作为记录器,则可以使用以下内容(仅显示绑定而不显示结果):

<appender
    name="STDOUT"
    class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -
            %msg%n</pattern>
    </encoder>
    <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
        <evaluator>
            <expression>return message.toLowerCase().contains("org.hibernate.type") &amp;&amp;
                logger.startsWith("returning");</expression>
        </evaluator>
        <OnMismatch>NEUTRAL</OnMismatch>
        <OnMatch>DENY</OnMatch>
    </filter>
</appender>

org.hibernate.SQL = DEBUG打印Query

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

org.hibernate.type = TRACE打印绑定,通常是结果,它将通过自定义过滤器进行抑制

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

您需要janino依赖(http://logback.qos.ch/manual/filters.html#JaninoEventEvaluator):

<dependency>
    <groupId>org.codehaus.janino</groupId>
    <artifactId>janino</artifactId>
    <version>2.6.1</version>
</dependency>

14
投票

在EclipseLink中,为了在运行时获取特定Query的SQL,您可以使用DatabaseQuery API:

Query query = em.createNamedQuery("findMe"); 
Session session = em.unwrap(JpaEntityManager.class).getActiveSession(); 
DatabaseQuery databaseQuery = ((EJBQueryImpl)query).getDatabaseQuery(); 
databaseQuery.prepareCall(session, new DatabaseRecord());

String sqlString = databaseQuery.getSQLString();

这个SQL会包含什么?用于参数。要使用参数转换SQL,您需要具有参数值的DatabaseRecord。

DatabaseRecord recordWithValues= new DatabaseRecord();
recordWithValues.add(new DatabaseField("param1"), "someValue");

String sqlStringWithArgs = 
         databaseQuery.getTranslatedSQLString(session, recordWithValues);

资料来源:How to get the SQL for a Query


7
投票

要查看OpenJPA中的所有SQL和参数,请将这两个参数放在persistence.xml中:

<property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/>
<property name="openjpa.ConnectionFactoryProperties" value="PrintParameters=true" />

4
投票

如果要查看与参数值和返回值完全相同的查询,可以使用jdbc代理驱动程序。它将拦截所有jdbc调用并记录它们的值。一些代理人:

  • log4jdbc
  • jdbcspy

它们还可以提供一些其他功能,例如测量查询的执行时间和收集统计信息。


4
投票

使用log4j的示例(src \ log4j.xml):

<?xml version="1.0" encoding="UTF-8" ?>

<appender name="CA" class="org.apache.log4j.AsyncAppender">
    <param name="BufferSize" value="512"/>
    <appender-ref ref="CA_OUTPUT"/>
</appender>
<appender name="CA_OUTPUT" class="org.apache.log4j.ConsoleAppender">
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="[%p] %d %c %M - %m%n"/>
    </layout>
</appender>

<logger name="org.hibernate.SQL" additivity="false">
    <level value="DEBUG"/>
    <appender-ref ref="CA"/>
</logger>

<root>
    <level value="WARN"/>
    <appender-ref ref="CA"/>
</root>


1
投票

此外,如果使用WildFly / JBoss,请将org.hibernate的日志记录级别设置为DEBUG

Hibernate Logging in WildFly


1
投票

如果您使用的是Spring框架。修改application.properties文件,如下所示

#Logging JPA Queries, 1st line Log Query. 2nd line Log parameters of prepared statements 
logging.level.org.hibernate.SQL=DEBUG  
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE  

#Logging JdbcTemplate Queries, 1st line Log Query. 2nd line Log parameters of prepared statements 
logging.level.org.springframework.jdbc.core.JdbcTemplate=DEBUG  
logging.level.org.springframework.jdbc.core.StatementCreatorUtils=TRACE  
© www.soinside.com 2019 - 2024. All rights reserved.