如何打印 LIMIT 和 OFFSET 的 SQL 参数

概括

我正在使用 JPA (Hibernate) 编写代码,并想检查日志中的 LIMIT 和 OFFSET 参数。

我添加了 Logback 并正确设置了日志级别,但我无法执行上述操作。我怎样才能做到这一点?

环境

  • 采用OpenJDK 11.0.4

  • 休眠 5.4.4.Final

  • Logback 经典版 1.2.3

  • MySQL 8.0.17

logback.xml

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

<!DOCTYPE configuration>

<configuration>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">

        <encoder>

            <pattern>[%-5level][%-10thread] %logger{36} - %msg%n</pattern>

        </encoder>

    </appender>


    <root level="INFO">

        <appender-ref ref="STDOUT"/>

    </root>


    <!-- Print SQL to log-->

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

    <logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" />

</configuration>

我的 Java 代码使用 JPA

EntityManagerFactory emf = Persistence.createEntityManagerFactory("FooPU");

EntityManager em = emf.createEntityManager();

String jpql = "SELECT f FROM Foo f ORDER BY f.id";


// Specify LIMIT and OFFSET

List<Foo> fooList =  = em.createQuery(jpql, Foo.class)

        .setFirstResult(1)

        .setMaxResults(3)

        .getResultList();


for (Foo f : fooList) {

    System.out.println(f);

}

em.close();

emf.close();

日志(实际)

没有显示 LIMIT 和 OFFSET 的参数。我只能看到一个 SQL。


[DEBUG][main      ] org.hibernate.SQL - select foo0_.id as id1_1_, ... from Foo foo0_ order by foo0_.id limit ?, ?

附带说明一下,其他 SQL 参数已正确显示。


[DEBUG][main      ] org.hibernate.SQL - select foo0_.id as id1_0_0_, ... from Foo foo0_ where foo0_.id=?

[TRACE][main      ] o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [10]

日志(预期)

[DEBUG][main      ] org.hibernate.SQL - select foo0_.id as id1_1_, ... from Foo foo0_ order by foo0_.id limit ?, ?

[TRACE][main      ] o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1]

[TRACE][main      ] o.h.type.descriptor.sql.BasicBinder - binding parameter [2] as [INTEGER] - [3]


慕尼黑8549860
浏览 178回答 3
3回答

翻阅古今

可能,它现在不支持。PreparedStatement通常参数通过ValueBinder接口(实际上是扩展类BasicBinder)绑定到一个,BasicBinder具有将绑定参数打印到日志的功能。但是 limit/offset 参数绑定到一个PreparedStatement没有ValueBinder接口的,因此 limit/offset 参数不会打印到日志中。我建议创建一个支持打印限制/偏移参数到日志的新问题!!

当年话下

您可以使用:setFirstResult(0).setMaxResults(5); 如果你使用 entityManager,它可以是这样的:entityManager.createQuery("yourQuery").setFirstResult(0).setMaxResults(5);

米脂

您正在撰写 JPQL 请求,JPA 不允许在其中使用关键字 LIMIT/OFFSET。调用 setFirstResult(1) 和 setMaxResults(3) 不会将 OFFSET 和 LIMIT 子句附加到查询。第一个选项是对您的数据库使用本机 SQL 查询,但这会使代码不可移植。另一种选择是使用 Pageable 来检索结果(不确定它是否会为您生成预期的日志行,但您需要检查):@Query("SELECT f FROM Foo f ORDER BY f.id DESC") // or ASCList<Foo> getLastDetails(Pageable pageable);List<Foo> fooList = getLastDetails(new PageRequest(0,1)); // (int page, int size)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java