日志记录选项是特定于提供商的。您需要知道您使用的是哪种 JPA 实现。
Hibernate(见这里):
EclipseLink(见这里):
OpenJPA(参见此处):
DataNucleus(参见此处):将日志类别 DataNucleus.Datastore.Native 设置为一个级别,例如 DEBUG。
此外,如果您正在使用 EclipseLink 并且想要输出 SQL 参数值,您可以将此属性添加到您的 persistence.xml 文件中:
<property name="eclipselink.logging.parameters" value="true"/>
如果您使用 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") &&
logger.startsWith("returning");</expression>
</evaluator>
<OnMismatch>NEUTRAL</OnMismatch>
<OnMatch>DENY</OnMatch>
</filter>
</appender>
org.hibernate.SQL=DEBUG 打印查询
<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>
在 EclipseLink 中,要在运行时获取特定查询的 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
我制作了一份我认为对其他人有用的备忘单。在所有示例中,如果您想将记录的查询保留在一行中(没有漂亮的打印),您可以删除 format_sql
属性。
将 SQL 查询漂亮地打印到标准输出,无需准备语句的参数,也无需优化日志框架:
application.properties
文件:
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
application.yml
文件:
spring:
jpa:
show-sql: true
properties:
hibernate:
format_sql: true
使用日志框架使用准备好的语句参数漂亮地打印 SQL 查询:
application.properties
文件:
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
application.yml
文件:
spring:
jpa:
properties:
hibernate:
format_sql: true
logging:
level:
org:
hibernate:
SQL: DEBUG
type:
descriptor:
sql:
BasicBinder: TRACE
漂亮的打印 SQL 查询,没有使用日志框架准备好的语句的参数:
application.properties
文件:
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=DEBUG
application.yml
文件:
spring:
jpa:
properties:
hibernate:
format_sql: true
logging:
level:
org:
hibernate:
SQL: DEBUG
来源(以及更多详细信息):https://www.baeldung.com/sql-logging-spring-boot
为了查看 OpenJPA 中的所有 SQL 和参数,将这两个参数放在 persistence.xml 中:
<property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/>
<property name="openjpa.ConnectionFactoryProperties" value="PrintParameters=true" />
如果您想查看带有参数值和返回值的确切查询,您可以使用 jdbc 代理驱动程序。它将拦截所有 jdbc 调用并记录它们的值。一些代理:
log4jdbc
jdbcspy
它们还可能提供一些附加功能,例如测量查询的执行时间和收集统计信息。
使用 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>
另一个 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.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());
此外,如果使用 WildFly/JBoss,请将 org.hibernate 的日志记录级别设置为 DEBUG
https://i.stack.imgur.com/cV0mR.png
如果您使用的是 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
请参阅Can't make hibernate stop showing SQL using Spring JPA Vendor Adapter
使用 Spring Boot,只需将 spring.jpa.show-sql=true 添加到 application.properties。这将显示查询但没有实际参数(您将看到 ? 而不是每个参数)。
在探索性开发期间,为了将 SQL 调试日志记录集中在我要检查的特定方法上,我使用以下记录器语句装饰该方法:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Level;
((ch.qos.logback.classic.Logger) LoggerFactory.getLogger("org.hibernate.SQL")).setLevel(Level.DEBUG);
entityManager.find(Customer.class, customerID);
((ch.qos.logback.classic.Logger) LoggerFactory.getLogger("org.hibernate.SQL")).setLevel(Level.INFO);
EclipseLink 输出 SQL(persistence.xml 配置):
<property name="eclipselink.logging.level.sql" value="FINE" />
JPA 提供者可以为您设置 - 如果有人不想通过 JPA 属性进行控制
public static JpaProperties properties() {
final JpaProperties jpaProperties = new JpaProperties();
jpaProperties.setShowSql(true);
对于需要从 javax.persistence.Query 验证 SQL 的任何人
import org.hibernate.query.Query;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.Query;
@RequestScoped
public class QueryServices {
@Inject
protected EntityManager entityManager;
public Query buildQuery(String searchCriteria) {
return entityManager.createNativeQuery("select * from table t where t.animal = ?1"))
.setParameter(1, searchCriteria);
}
class QueryServicesTest {
@Test
void buildQuerySqlGenerationTest() {
final String searchFor = "cat";
// Build a query object to check
org.hibernate.query.Query query = workflowServices.buildQuery(searchFor)
.unwrap(org.hibernate.query.Query.class).getQueryString();
// Validate the generated sql contains the search value
Assertions.assertTrue(query.contains(searchFor);
}
}
有一个文件叫persistence.xml 按Ctrl+Shift+R 找到,然后,有个地方写了showSQL之类的东西。
把它当作真的
我不确定服务器是否必须以调试模式启动。检查在控制台上创建的 SQL。
不定期副业成功案例分享