4

有没有办法限制在 Tomcat 应用程序中的 Oracle 数据源级别返回的行?

似乎maxRows只有在 Java 代码中的数据源上设置它才可用。放置maxRows="2"数据源不适用。

有没有其他方法限制返回的行?无需更改代码?

4

6 回答 6

4

它不是在配置级别可用的东西。您可能需要仔细检查它是否完成了您希望它执行的操作:请参阅 setMaxRows 的 javadoc。使用 Oracle,它仍然会为查询取回每一行,然后只删除范围之外的行。您确实需要使用 rownum 才能使其与 Oracle 一起正常工作,而在配置中您也不能这样做。

于 2008-11-26T11:21:21.347 回答
1

问题是为什么要限制返回的行数。这样做可能有很多原因。首先是限制数据库返回的数据。在我看来,这在大多数情况下是没有意义的,好像我只想获取某些数据然后我会使用不同的语句或添加过滤条件或其他东西。例如,如果您使用 Oracle 的 rownum,您并不完全知道哪些数据在您获得的行中,哪些数据不包括在内,因为您只是告诉数据库您想要行 x 到 y。
第二种方法是限制内存使用并提高性能,以便您从 JDBC 驱动程序获得的 ResultSet 不会包含所有数据。您可以使用Statement.setFetchSize()限制 ResultSet 保存的行数. 如果将 ResultSet 中的游标移动到超出获取的行数,则 JDBC 驱动程序将从数据库中获取丢失的数据。(在 Oracle 的情况下,数据库会将数据存储在 JDBC 驱动程序直接访问的引用游标中)。

于 2008-11-28T10:05:13.760 回答
1

*注意:下面的代码是作为纯示例提供的。它尚未经过测试 *因此可能会伤害您自己或您的计算机,甚至会打您的脸。

如果您想避免修改 SQL 查询但仍希望拥有干净的代码(这意味着您的代码保持可维护性),您可以使用包装器设计解决方案。也就是说,通过使用包装现有类的一小组类,您可以无缝地为应用程序的其余部分实现您想要的,这些应用程序仍然认为它正在使用真实的数据源、连接和语句。

1 - 实现 StatementWrapper 或 PreparedStatementWrapper 类,具体取决于您的应用程序已经使用的内容。这些类是普通 Statement 或 PreparedStatement 实例的包装器。它们被简单地实现为使用内部语句作为完成所有工作的委托,除非这是一个 QUERY 语句(Statement.executeQuery() 方法)。只有在那种精确的情况下,包装器才会用以下两个字符串包围查询:“SELECT * FROM (” and ") WHERE ROWNUM < "+maxRowLimit。有关基本代码包装器代码,请参阅下面的 DataSourceWrapper 查找方式。

2 - 再写一个包装器:ConnectionWrapper,它包装一个 Connection,它在 createStatement() 中返回 StatementWrapper,在 prepareStatement() 中返回 PreparedStatementWrapper。这些是以前编码的类,将 ConnectionWrapper 的 delegateConnection.createStatement()/prepareStatement() 作为构造参数。

3 - 使用 DataSourceWrapper 重复该步骤。这是一个简单的代码示例。

public class DataSourceWrapper implements DataSource
{
    private DataSource mDelegate;

    public DataSourceWrapper( DataSource delegate )
    {
        if( delegate == null ) { throw new NullPointerException( "Delegate cannot be null" );
        mDelegate = delegate;
    }

    public Connection getConnection(String username, String password)
    {
        return new ConnectionWrapper( mDelegate.getConnection( username, password ) );
    }

    public Connection getConnection()
    {
        ... <same as getConnection(String, String)> ...
    }
}

4 - 最后,使用该 DataSourceWrapper 作为应用程序的 DataSource。如果您使用的是 JNDI (NamingContext),则此更改应该是微不足道的。

编写所有这些代码非常快速且非常简单,尤其是如果您使用像 Eclipse 或 IntelliJ 这样的智能 IDE,它们将自动实现委派方法。

于 2011-02-24T15:18:48.800 回答
0

如果您知道您将只处理一个表,则在 where 语句中定义一个带有 rownum 的视图以限制行数。通过这种方式,行数在 DB 中得到控制,不需要在客户端应用程序的任何查询中指定。如果要更改返回的行数,请在执行查询之前重新定义视图。

一种更动态的方法是开发一个过程并传入许多行,并让该过程向您的客户端返回一个 ref_cursor。这将具有避免对数据库进行硬解析并提高性能的优势。

于 2008-11-26T20:43:05.627 回答
0

好的,然后必须进行代码更改。

该场景限制了临时报告工具,以便最终用户不会撤回太多记录并生成无法使用的报告。

我们已经使用了基于 Oracle 成本的资源管理。

于 2008-12-02T08:25:04.447 回答
0

请查看此页面,其中描述了限制一次吸入 Java 应用程序的数量。正如另一篇文章指出的那样,数据库仍将提取所有数据,这更多是为了控制网络使用和 Java 端的内存。

于 2009-02-20T14:55:28.203 回答