MyBatis RowBounds不限制查询结果

ode*_*dia 4 sql oracle spring mybatis

我正在开发一个需要支持分页的无状态API.

我使用的是Oracle数据库.我使用Spring和MyBatis进行数据库访问.

从文档中,我了解到我可以使用RowBounds类来限制查询返回的行数.

但是,似乎没有对查询进行特殊优化以支持分页.

例如,如果我将RowBounds设置为使用50条记录偏移100,我希望查询添加以下内容:

(original query with the where clause...)
and ROWNUM < 150
and ROWNUM >= 100
Run Code Online (Sandbox Code Playgroud)

但那里什么也没有,只是我手动定义的查询.

这对性能来说太糟糕了,因为我可能有几千个结果.

我究竟做错了什么?

谢谢.

kha*_*son 8

Mybatis留下许多东西,直到SQL driver正在使用的东西,似乎周围的确切行为RowBounds是其中之一.

请参阅http://mybatis.github.io/mybatis-3/java-api.html,特别是以下部分:

在这方面,不同的驱动者能够实现不同的效率水平.为获得最佳性能,请使用SCROLL_SENSITIVE或SCROLL_INSENSITIVE的结果集类型(换句话说:不是FORWARD_ONLY).

显然是默认值UNSET,但您可以尝试将其SCROLL_SENSITIVE用作标记中的ResultSetType属性select,看看是否有帮助.有关详细信息,请参阅http://mybatis.github.io/mybatis-3/sqlmap-xml.html.

如果不工作,你总是可以解决的问题,通过开沟使用RowBounds并实施SettingsBean类(或类似),您的select标签将采取作为parameterType,以及其中包含的字段offsetlimit(或也许rowStartrowEnd作出更有意义Oracle,然后您可以根据需要在运行时设置它们,并在执行时将它们动态插入到SQL中select.

虽然代码更多,但您可以通过纯动态SQL完全按照自己的意愿控制行为.我已经使用了这样的方法,Mybatis而且Postgres效果很好.

因此,您将使用这些字段及其getter和setter 实现SettingsBean类,然后您的select语句可能如下所示:

<select
  id="selectFoo"
  parameterType="com.foo.bar.SettingsBean">

select *
from foo
where rownum >= #{rowStart}
  and rownum < #{rowEnd}
</select>
Run Code Online (Sandbox Code Playgroud)

  • 谢谢.似乎RowBounds永远不会使用Oracle rownum技术.另外,似乎resultSetType设置仅与有状态的基于Web的应用程序相关,例如显示分页结果的网页.我正在使用Spring和MyBatis的无状态EJB,所以我收集它会在我的情况下产生0差异?好像我将不得不重新使用rownum解决方案.我真的认为MyBatis团队应该更清楚地传达RowBounds的局限性.他们将其描述为一种简单的抽象方式来进行分页,而事实上它的使用非常有限. (2认同)

Boa*_*ode 5

我找到了解决此问题的简单方法。我按照Mybatis的说明@khampson的建议进行操作,并且正在将RowBounds实例传递给映射器,而没有强制执行任何限制。

RowBounds rowbounds = new RowBounds(0, resultLimit);
roster = tableMapper.selectAll(rowbounds);
Run Code Online (Sandbox Code Playgroud)

映射器Java

public List<Row> selectAll(RowBounds rowbounds);
Run Code Online (Sandbox Code Playgroud)

映射器XML

<select id="com.TableMapper.selectAll" resultMap="row" timeout="10">
            SELECT * FROM table;
</select>
Run Code Online (Sandbox Code Playgroud)

只需将“ LIMIT#{param1.offset},#{param1.limit}”附加到映射器的xml即可产生我想要的行为!

<select id="com.TableMapper.selectAll" resultMap="row" timeout="10"> 
    SELECT * FROM table LIMIT #{param1.offset}, #{param1.limit}; 
</select>
Run Code Online (Sandbox Code Playgroud)