Hibernate、MySQL、批次之间的关系、JDBC 个连接和 JDBC 个语句
Hibernate, MySQL, relationship between batches, JDBC connections and JDBC statements
目前正在开发一个使用休眠和 MySQL 的应用程序。我在日志中看到以下输出,这让我感到惊讶:
Hibernate: select user0_.id as id1_3_, user0_.email as email2_3_, user0_.name as name3_3_ from test_user user0_ order by user0_.name asc limit ?, ?
Hibernate: select count(user0_.id) as col_0_0_ from test_user user0_
2022-05-11 10:49:23.650 INFO 21384 --- [ main] i.StatisticalLoggingSessionEventListener : Session Metrics {
441906 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
2709671 nanoseconds spent preparing 2 JDBC statements;
8478990 nanoseconds spent executing 2 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
16820 nanoseconds spent executing 2 partial-flushes (flushing a total of 0 entities and 0 collections)
}
我没想到这个输出是因为:
- 有 2 个查询对应于 2 个 JDBC 语句
- 有0个批次
- 只有一个JDBC连接
我期望的是以下之一:
- 1 个批处理、2 个语句和一个用于执行批处理的连接
- 0 个批次,2 个语句,2 个连接(每个语句一个)
怎么可能有 0 个批次并仍然在一个连接中执行 2 个查询?
听起来你认为batch == transaction,但这不是JDBC中使用的意思。在Java/JDBC中,batch execution有特定的含义,我假设Hibernate也有同样的含义:使用Statement.executeBatch()执行多个update/delete/insert语句。这在这里绝对不适用,因为您不能在 JDBC 中批处理 selects,即使对于 update/delete/insert,您通常也只会在有多组参数要执行时进行批处理一个准备好的语句。
在这里,Hibernate 在同一个连接(和同一个事务)上执行第一条语句,然后执行第二条语句。根据需要,它可能会交错处理两个 select 语句的结果集(JDBC 允许在不在 auto-commit 中时来自不同语句对象的多个打开结果集)。
目前正在开发一个使用休眠和 MySQL 的应用程序。我在日志中看到以下输出,这让我感到惊讶:
Hibernate: select user0_.id as id1_3_, user0_.email as email2_3_, user0_.name as name3_3_ from test_user user0_ order by user0_.name asc limit ?, ?
Hibernate: select count(user0_.id) as col_0_0_ from test_user user0_
2022-05-11 10:49:23.650 INFO 21384 --- [ main] i.StatisticalLoggingSessionEventListener : Session Metrics {
441906 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
2709671 nanoseconds spent preparing 2 JDBC statements;
8478990 nanoseconds spent executing 2 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
16820 nanoseconds spent executing 2 partial-flushes (flushing a total of 0 entities and 0 collections)
}
我没想到这个输出是因为:
- 有 2 个查询对应于 2 个 JDBC 语句
- 有0个批次
- 只有一个JDBC连接
我期望的是以下之一:
- 1 个批处理、2 个语句和一个用于执行批处理的连接
- 0 个批次,2 个语句,2 个连接(每个语句一个)
怎么可能有 0 个批次并仍然在一个连接中执行 2 个查询?
听起来你认为batch == transaction,但这不是JDBC中使用的意思。在Java/JDBC中,batch execution有特定的含义,我假设Hibernate也有同样的含义:使用Statement.executeBatch()执行多个update/delete/insert语句。这在这里绝对不适用,因为您不能在 JDBC 中批处理 selects,即使对于 update/delete/insert,您通常也只会在有多组参数要执行时进行批处理一个准备好的语句。
在这里,Hibernate 在同一个连接(和同一个事务)上执行第一条语句,然后执行第二条语句。根据需要,它可能会交错处理两个 select 语句的结果集(JDBC 允许在不在 auto-commit 中时来自不同语句对象的多个打开结果集)。