gpt4 book ai didi

java - 为什么 JDBC 不支持批量获取数据?

转载 作者:行者123 更新时间:2023-11-30 08:48:41 25 4
gpt4 key购买 nike

JDBC 长期以来一直使用 addBatchexecuteBatch 支持批量更新。为什么不支持添加一堆准备好的语句并获取一组结果集作为响应?

例如,如果我想为单个 View 加载客户详细信息、基本账户详细信息、基本卡详细信息、基本贷款详细信息等,我更愿意创建一堆准备好的语句并将准备好的语句附加到 ArrayList并将它们作为批处理执行。然后我会遍历结果集并处理数据。希望可以节省几个网络往返(假设我的查询是高性能的)。

查询示例:

SELECT custid, first, last, age FROM Customer where custid = ?
SELECT custid, acno, accountname, accounttype, status FROM Account where custid = ?
SELECT custid, cardno, cardname, cardtype, status FROM CreditCard where custid = ?
SELECT custid, loanno, principal, rate FROM Loan where custid = ?

我可以想象几个假设的原因,为什么这可能是个坏主意。但是,我不确定在现实世界中哪个最有可能是真实的。

反对批量获取的假设原因:

  1. 存在一些与基础网络/数据库堆栈/内存相关的问题这可以防止一堆选择查询在同一个上执行连接和结果集保持打开状态。
  2. 响应处理代码会过于繁琐,因为在调用级别和单个语句级别可能存在异常。而且,必须正确关闭多个语句。
  3. 减少网络调用次数不会显着提高性能。查询执行是主要瓶颈,网络往返成本微不足道。
  4. 可能存在滥用此功能的情况。像这样与其他查询批量处理的单个性能不佳的查询可能会导致应用程序性能不佳。

之所以这么问,是因为我经常看到很多Join查询将父子关系合并到一个SQL查询中,只是为了在一次调用中完成加载。

然而,随着表数量的增长,查询变得复杂。此外,父表信息在每个子表的每一行中重复。因此,单个连接结果集中存在大量数据冗余。

示例连接查询:

SELECT custid, first, last, age, acno, accountname, accounttype, a.status, cardno, cardname, cardtype, c.status, loanno, principal, rate
FROM Customer cc, Account a, CreditCard c, Loan l
WHERE a.custid=CC.custid(+) and c.custid=CC.custid(+) and l.custid=CC.custid(+)

最佳答案

JDBC API 确实支持这一点。

Statement.getMoreResults() 可以告诉您通过execute() 执行的S​​QL 语句是否产生了多个ResultSet

引自 JavaDocs for getMoreResults() :

Moves to this Statement object's next result, returns true if it is a ResultSet object, and implicitly closes any current ResultSet object(s) obtained with the method getResultSet.

There are no more results when the following is true:

// stmt is a Statement object<br>
((stmt.getMoreResults() == false) && (stmt.getUpdateCount() == -1))

然而,它取决于后端 DBMS 和 JDBC 驱动程序如果您可以使用它。一些 JDBC 驱动程序只是拒绝通过单个 execute() 调用运行多个语句(主要是作为一种防止 SQL 注入(inject)的方法),其他驱动程序则不会。

所以在例如Postgres 你可以这样做:

boolean hasResult = stmt.execute(
"select * from table_1;\n" +
"select * from table_2;");

while (hasResult)
{
rs = stmt.getResultSet();
while (rs.next())
{
// process the result set
}
hasResult = stmt.getMoreResults();
}

这甚至允许混合 SELECT 和例如UPDATE 语句,如果您还检查 getUpdateCount()

据我所知,您也可以使用 SQL Server 执行此操作。它不适用于 Oracle。

虽然我还没有用 PreparedStatement 尝试过。但由于 getMoreResults() 是为 Statement 定义的,它也可用于 PreparedStatement

关于java - 为什么 JDBC 不支持批量获取数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31785089/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com