如何在内存数据库中设置 fetchSize?

Posted

技术标签:

【中文标题】如何在内存数据库中设置 fetchSize?【英文标题】:How do I set fetchSize in memory db? 【发布时间】:2018-11-02 07:09:00 【问题描述】:

最近我正在研究 Junit 以使用 hsqldb(2.3.3) 测试 Dao 相关代码。系统正在使用mybatis进行数据持久化。

在mybatisXXsql.xml中,select语句中有“fetchSize”属性,如:

<select ... resultSetType="FORWARD_ONLY" fetchSize="-2147483648">
    ...
</select>

当我们调用使用 hsqldb 测试 sql 时,它显示以下异常:

Caused by: java.sql.SQLException: Invalid argument in JDBC call
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCUtil.outOfRangeArgument(Unknown Source)
    at org.hsqldb.jdbc.JDBCPreparedStatement.setFetchSize(Unknown Source)

我检查了它似乎不支持内存数据库中的“fetchSize”,有人能给我一些建议,我该如何测试这个 sql 部分?

【问题讨论】:

【参考方案1】:

JDBC 的负 fetchSize 是 not supported。以下是setFetchSize 抛出的异常的描述:

SQLException - 如果发生数据库访问错误,则在关闭的 Statement 上调用此方法或不满足条件 rows >= 0。

错误的原因是获取大小不正确(堆栈跟踪中的outOfRangeArgument 也表明了这一点)。

mysql 驱动程序确实支持Integer.MIN_INT 作为获取大小来指定结果集处于流模式:

只进、只读结果集与 Integer.MIN_VALUE 提取大小的组合用作驱动程序逐行流式传输结果集的信号。在此之后,将逐行检索使用该语句创建的任何结果集。

mybatis 本身不允许在映射器配置中参数化fetchSize

您需要使用一些技术来通过AspectJPowerMock 覆盖配置。使用PowerMock,您可以在调用执行查询的方法之前使用PowerMock.stub 执行类似的操作:

PowerMock.stub(
   PowerMock.method(
       org.apache.ibatis.mapping.MappedStatement.class,
       "getFetchSize"
   )
).toReturn(1);

这样当mybatis创建Statement时,它会使用fetchSize的模拟值

【讨论】:

感谢您的解释。那么我该如何测试这部分,或者我可以模拟这部分以重置 fetchSize? 我已经用如何解决这个问题的选项更新了答案

以上是关于如何在内存数据库中设置 fetchSize?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用hibernate jpa在内存数据库中设置h2?

如何在 RStudio(桌面版)中设置内存限制?

Eclipse 中设置JVM 内存

如何在.htaccess文件中设置PHP最大执行时间和脚本内存限制

如何在.htaccess文件中设置PHP最大执行时间和脚本内存限制

如何在apache中设置每个连接的最大请求数