为了通过减少多个DB调用来实现更好的性能,我想在同一个DB调用中执行多个select查询。我使用的是PostgreSQL数据库(版本14.9),Java(版本17)和Springboot(版本3.0.6)。
下面是我的代码:
private final EntityManager entityManager;
final List<Object[]> results =
entityManager.createNativeQuery("select * from roles where role_id <= 200; select * from departments where department_id <= 50")
.getResultList();
字符串
下面是我得到的错误:
jakarta.persistence.PersistenceException: Converting `org.hibernate.exception.GenericJDBCException` to JPA `PersistenceException` : JDBC exception executing SQL [select * from roles where role_id <= 200; select * from departments where department_id <= 50]
........
........
........
........
........
Caused by: org.hibernate.exception.GenericJDBCException: JDBC exception executing SQL [select * from roles where role_id <= 200; select * from departments where department_id <= 50]
........
........
........
........
........
Caused by: org.postgresql.util.PSQLException: Multiple ResultSets were returned by the query.
at org.postgresql.jdbc.PgStatement.getSingleResultSet(PgStatement.java:257)
at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:138)
at org.hibernate.sql.results.jdbc.internal.DeferredResultSetAccess.executeQuery(DeferredResultSetAccess.java:217)
型
我试了下面的代码:
private final EntityManager entityManager;
final List<Object[]> results =
entityManager.createNativeQuery("select * from roles where role_id <= 200; select * from departments where department_id <= 50")
.getResultList();
型
我期待在“结果”列表对象2结果集。
3条答案
按热度按时间c2e8gylq1#
你已经在给自己制造麻烦了,因为你在没有限制参数的情况下从两个不同的表中选择 *。
您可以创建一个存储过程并选择所需的任何列,也可以执行嵌套的select语句并使用它进行查询。您始终可以获得单个结果集并使用它。参考Spring Boot, JPA / Hibernate: How to execute two raw SELECT queries at once?
但是你所指的性能下降并不是由于多个数据库查询,而是由于没有limit参数的select * 语句。
u7up0aaq2#
这不是Hibernate的工作方式,Hibernate不允许你传递一个以上的查询。
如果你真的想这样做,你可以使用
UNION ALL
。但是我不知道你的roles
和department
表中的列数是否匹配。你的方法根本不会起作用,或者即使你使用
UNION ALL
,这也不是一个好的做法,因为你试图从两个不同的表中获取结果。wh6knrhe3#
对于Hibernate和JPA entityManager,NativeQuery()通常期望单个查询,而不是由一个子对象分隔的多个查询,并且在您的情况下,UNION可能无法工作,因为您正在查询不相互引用的不同实体,但收集主值。
当查询不同的实体以将主条目收集到一个结果集中时,我通常会想到两个选项:
**使用存储过程:**示例存储过程将多个主值(当不可能/不需要关系查询时)收集到一个JSON对象中。这可能会减少您的往返次数。
字符串
我过去曾多次使用这种方法来查询和收集结果集中的不同实体集。
或者使用JDBC Batch:
型
(我还没有尝试过,只是一个想法,如果它有帮助)