2009-12-31 55 views
15

¿Cómo convierto el objeto Resultset a una vista paginada en un JSP?ResultSet para Pagination

Por ejemplo, este es mi consulta y conjunto de resultados:

pst = con.prepareStatement("select userName, job, place from contact"); 
rs = pst.executeQuery(); 

Respuesta

35

Para comenzar, debe agregar uno o dos parámetros de solicitud adicionales al JSP: firstrow y (opcionalmente) rowcount. El rowcount también se puede dejar y definir completamente en el lado del servidor.

A continuación, añadir un montón de botones de paginación a la JSP: el siguiente botón debe instruir al Servlet para incrementar el valor de firstrow con el valor de rowcount. El botón anterior obviamente disminuirá el valor de firstrow con el valor rowcount. ¡No olvide manejar valores negativos y desbordamientos correctamente! Puede hacerlo con la ayuda de SELECT count(id).

A continuación, active una consulta SQL específica para recuperar una sublista de los resultados. Sin embargo, la sintaxis SQL exacta depende de la base de datos utilizada.En MySQL y PostgreSQL es fácil con LIMIT y OFFSET cláusulas:

private static final String SQL_SUBLIST = "SELECT id, username, job, place FROM" 
    + " contact ORDER BY id LIMIT %d OFFSET %d"; 

public List<Contact> list(int firstrow, int rowcount) { 
    String sql = String.format(SQL_SUBLIST, firstrow, rowcount); 

    // Implement JDBC. 
    return contacts; 
} 

en Oracle necesita una sub consulta con rownum cláusula que debe ser similar:

private static final String SQL_SUBLIST = "SELECT id, username, job, place FROM" 
    + " (SELECT id, username, job, place FROM contact ORDER BY id)" 
    + " WHERE ROWNUM BETWEEN %d AND %d"; 

public List<Contact> list(int firstrow, int rowcount) { 
    String sql = String.format(SQL_SUBLIST, firstrow, firstrow + rowcount); 

    // Implement JDBC. 
    return contacts; 
} 

En DB2 se necesita la función OLAP row_number() de esto:

private static final String SQL_SUBLIST = "SELECT id, username, job, place FROM" 
    + " (SELECT row_number() OVER (ORDER BY id) AS row, id, username, job, place" 
    + " FROM contact) AS temp WHERE row BETWEEN %d AND %d"; 

public List<Contact> list(int firstrow, int rowcount) { 
    String sql = String.format(SQL_SUBLIST, firstrow, firstrow + rowcount); 

    // Implement JDBC. 
    return contacts; 
} 

No hago MSSQL, pero es sintácticamente similar a DB2. También vea this topic.

Por último, simplemente presente la sublista en la página JSP de la forma habitual con JSTL c:forEach.

<table> 
    <c:forEach items="${contacts}" var="contact"> 
     <tr> 
      <td>${contact.username}</td> 
      <td>${contact.job}</td> 
      <td>${contact.place}</td> 
     </tr> 
    </c:forEach> 
</table> 
<form action="yourservlet" method="post"> 
    <input type="hidden" name="firstrow" value="${firstrow}"> 
    <input type="hidden" name="rowcount" value="${rowcount}"> 
    <input type="submit" name="page" value="next"> 
    <input type="submit" name="page" value="previous"> 
</form> 

en cuenta que algunos pueden sugieren que es necesario SELECT toda la tabla y guardar la List<Contact> en el ámbito de la sesión y hacer uso de List#subList() paginar. Pero esto es de memoria eficiente con miles filas y múltiples usuarios concurrentes.

Para aquellos que estén interesados ​​en una respuesta similar en contexto JSF/MySQL usando el componente h:dataTable, puede encontrar this article útil. También contiene algunas matemáticas agnósticas útiles para el lenguaje para lograr que la paginación "similar a Google" funcione bien.

+0

Supongamos que las inserciones y las inserciones de la base de datos se han producido mientras el usuario mira una página. Los números de fila no serán estables con el tiempo, creo? El efecto podría ser darle al usuario algunos cambios inesperados en la posición. – djna

+0

Esto no es una preocupación. No desea ver un elemento ya eliminado o perder datos editados. El único recurso para eso sería transportar toda la tabla de bases de datos a la memoria de Java y trabajar solo en eso, pero no quiere hacer eso. – BalusC

+0

@BalusC - wow. Impresionante respuesta. Puedo hacer un buen uso de mí mismo. – ChadNC

2

Aquí hay un par de cosas que puede hacer:

  • Marshall el conjunto de resultados a alguna lista de objetos/registros
  • Según el tamaño de página requerido, averigüe cuántas páginas tendrá en función del conjunto de resultados.
  • Compruebe el parámetro de solicitud para la página requerida y las compensaciones basadas en la cantidad de elementos que se mostrarán en la página. Por lo tanto, si está en la página 4 con 12 para mostrar, su desplazamiento es 48.
  • Determine el número total de páginas en función del recuento de los elementos.

  • mostrar los elementos basados ​​en el offset que determinó (sólo pantalla después del tema 48)

  • generar su paginación con la cantidad de páginas basado en el número total de páginas que determinados.

=======

Esa es su enfoque básico. Se pueden ajustar esto con:

  • La determinación de una manera de limitar la consulta a la página (pero esto no usted ayudar a determinar los tamaños de página)
  • formas de fantasía de la paginación
  • etc ..
+0

Esto no es muy eficiente si tiene un conjunto de resultados con miles de filas. En lugar de hacer la búsqueda en el nivel de la base de datos. – BalusC

+0

Él solo necesita un punto de partida. –

-1

Busque el patrón de lista de valores y aplíquelo. Esa suele ser la mejor manera de manejar este tipo de cosas.

3

Este ejemplo de Oracle es incorrecto.

Sí, en el exterior seleccione si tiene buenos valores ROWNUM, pero sigue siendo pseudocolumna por lo que no podemos usar BETWEEN en él. Necesitamos uno más select.

El código SQL es correcta:

SELECT c.* 
    FROM (SELECT c.*, ROWNUM as rnum 
      FROM (SELECT id, username, job, place FROM contact ORDER BY id) c) c 
WHERE c.rnum BETWEEN 5 AND 10 

Compañeros, usando cadena SQL sólida y clase Declaración es slooow. Oracle tiene que analizar su SQL cada vez que lo ejecute.

//Slooow example 
Satement stmt = con.createStatement(); 
ResultSet rs = stmt.executeQuery("select * from my_table where id = 11"); 

Use los parámetros PreparedStatement y binding.

//Faster example 
    PreparedStatement ps = conn.getPrepareStatement("select * from my_table where id = ?"); 
    ps.setInt(1, 11); 

Y la solución más rápida es poner su sql en el procedimiento almacenado de Oracle y usar CallableStatement para llamarlo.

//Fastest example 
CallableStatement cs = conn.prepareCall("{? = call my_plsql_function(?)}"); 
cs.setInt(1, 11); 
-1

Se puede utilizar para displaytag paigination o conjunto de resultados pero u descargar algún archivo jar displattag

primero se crea un servlet StudentList.java

public class StudentList extends HttpServlet 

{ servicio public void (solicitud de HttpServletRequest, HttpServletResponse respuesta) lanza ServletException, IOException {

 ArrayList al=new ArrayList(); 
     StudentDao stdo=new StudentDao(); // this is DAO Class (Data Acccess Object) 

     try 
     { 
      al=stdo.getStudentList(); //getstudent list dao method 
     } 
     catch (SQLException e) 
     { 
      e.printStackTrace(); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
     request.setAttribute("al",al); 

     RequestDispatcher rd=request.getRequestDispatcher("StudentPaging.jsp"); 
     rd.forward(request,response); 

} 

}

// DAO método

public ArrayList getStudentList() throws SQLException,Exception 
{ 
    ArrayList ai=new ArrayList(); 
    Connection con=null; 
    Statement st=null; 
    ResultSet rs=null; 
    Date dt=new Date(); 
    SimpleDateFormat sdf=new SimpleDateFormat("dd/MM/yyyy"); 
    StudentInformation sdata=null; 

    con=MyConnection.creatConnection(); 
    if(con!=null) 
    { 
     st=con.createStatement(); 
     String select="select * from STUDENT"; 
     System.out.println(select); 

     rs=st.executeQuery(select); 
     if(rs!=null) 
     { 
      while(rs.next()) 
      { 
       sdata=new StudentInformation(); 
       sdata.setSid(rs.getString("SID")); 
       sdata.setFirstName(rs.getString("FIRSTNAME")); 
       sdata.setMiddleName(rs.getString("MIDDLENAME")); 
       sdata.setLastName(rs.getString("LASTNAME")); 
       dt=rs.getDate("SDATE"); 
       sdata.setDateofbirth(sdf.format(dt)); 
       sdata.setGender(rs.getString("GENDER")); 
       sdata.setAddress(rs.getString("ADDRESS")); 
       sdata.setHigestQulification(rs.getString("HIQULIFICATION")); 
       sdata.setLanguageKnow(rs.getString("LANGUAGE")); 
       sdata.setHobby(rs.getString("HOBBY")); 
       sdata.setTermCondition(rs.getString("TERMCON")); 
       ai.add(sdata); 
      } 
     } 
    } 
    return ai; 
} 

enter image description here