首页 > 解决方案 > 如何在内存数据库中设置 fetchSize?

问题描述

最近在做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 部分?

标签: mysqljunitmybatishsqldb

解决方案


fetchSizeJDBC不支持负数。以下是setFetchSize引发的异常的描述:

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

错误的原因是 fetch size 不正确(outOfRangeArgument在堆栈跟踪中也暗示了这一点)。

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

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

mybatis 本身不允许fetchSize在 mapper 配置中进行参数化。

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

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

这样,当 mybatis 将创建一个Statement时,它将使用模拟值fetchSize


推荐阅读