java - traer - ¿Cómo limitar el número de filas devueltas desde Oracle en el nivel de fuente de datos JDBC?
select limitar numero de registros (6)
¿Hay alguna forma de limitar las filas devueltas en el nivel de fuente de datos de Oracle en una aplicación Tomcat?
Parece que maxRows
solo está disponible si lo configura en la fuente de datos en el código de Java. Poner maxRows="2"
en la maxRows="2"
datos no se aplica.
¿Hay algún otro límite de las filas devueltas? Sin un cambio de código?
No es algo que esté disponible en el nivel de configuración. Es posible que desee comprobar que hace lo que quiera que haga de todos modos: consulte el javadoc para setMaxRows . Con Oracle, va a recuperar todas las filas de la consulta y luego colocará las que están fuera del rango. Realmente necesitarías usar Rownum para que funcione bien con Oracle y no puedes hacer eso tampoco en la configuración.
Si sabe que tratará con una sola tabla, defina una vista con rownum en la instrucción where para limitar el número de filas. De esta forma, el número de filas se controla en la base de datos y no necesita ser especificado como parte de ninguna consulta desde una aplicación cliente. Si desea cambiar el número de filas devueltas, redefina la vista antes de ejecutar la consulta.
Un método más dinámico sería desarrollar un procedimiento y pasar varias filas, y hacer que el procedimiento devuelva un ref_cursor a su cliente. Esto tendría la ventaja de evitar un análisis riguroso en la base de datos y aumentar el rendimiento.
La pregunta es por qué quieres limitar el número de filas devueltas. Puede haber muchas razones para hacer esto. El primero sería limitar los datos devueltos por la base de datos. En mi opinión, esto no tiene sentido en la mayoría de los casos, como si quisiera obtener ciertos datos solo entonces usaría una declaración diferente o agregaría una condición de filtro o algo así. Por ejemplo, si usa rownum de Oracle, no sabe exactamente qué datos hay en las filas que obtiene y qué datos no están incluidos, ya que simplemente le dice a la base de datos que desea que la fila xay sea.
El segundo enfoque es limitar el uso de memoria y aumentar el rendimiento para que el ResultSet que obtienes del controlador JDBC no incluya todos los datos. Puede limitar el número de filas que contiene ResultSet utilizando Statement.setFetchSize () . Si mueve el cursor en ResultSet más allá de la cantidad de filas obtenidas, el controlador JDBC obtendrá los datos faltantes de la base de datos. (En el caso de Oracle, la base de datos almacenará los datos en un cursor de referencia al que accede directamente el controlador JDBC).
Ok, un cambio de código tendrá que ser entonces.
El escenario está limitando una herramienta de informe ad hoc para que el usuario final no retire demasiados registros y genere un informe que no se puede usar.
Ya usamos administración de recursos basada en costos oracle.
Eche un vistazo a esta página con una descripción de cómo limitar cuánto se absorbe en la aplicación Java a la vez. Como señala otra publicación, la base de datos aún extraerá todos los datos, esto es más para controlar el uso de la red y la memoria en el lado de Java.
* Cuidado: el código a continuación se proporciona como un ejemplo puro. No se ha probado *. Por lo tanto, puede dañarse a usted o a su computadora o incluso golpearse en la cara.
Si quiere evitar modificar sus consultas SQL pero quiere tener código limpio (lo que significa que su código puede mantenerse), puede diseñar la solución usando wrappers. Es decir, al usar un pequeño conjunto de clases que envuelven las existentes, puede lograr lo que quiere sin problemas para el resto de la aplicación, que seguirá creyendo que está funcionando con DataSource, Connection y Statement reales.
1: implemente una clase StatementWrapper o PreparedStatementWrapper, dependiendo de lo que su aplicación ya use. Esas clases son envoltorios alrededor de instancias normales de Statement o PreparedStatement. Se implementan simplemente como el uso de la declaración interna como un delegado que hace todo el trabajo, excepto cuando se trata de una instrucción QUERY (método Statement.executeQuery ()). Solo en esa situación precisa, el contenedor rodea la consulta mediante las dos cadenas siguientes: "SELECT * FROM (" y ") WHERE ROWNUM <" + maxRowLimit. Para el código de envoltura de código básico, vea cómo se ve el DataSourceWrapper a continuación.
2 - escriba una envoltura más: ConnectionWrapper que envuelve una conexión que devuelve StatementWrapper en createStatement () y PreparedStatementWrapper en prepareStatement (). Esas son las clases previamente codificadas que toman delegateConnection.createStatement () / prepareStatement () de ConnectionWrapper como argumentos de construcción.
3 - repite el paso con un DataSourceWrapper. Aquí hay un ejemplo de código simple.
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 - Finalmente, use ese DataSourceWrapper como el DataSource de su aplicación. Si está utilizando JNDI (NamingContext), este cambio debería ser trivial.
Codificar todo esto es rápido y sencillo, especialmente si está utilizando IDE inteligente como Eclipse o IntelliJ, que implementará los métodos de delegación automágicamente.