Как я преобразовываю объект Набора результатов в разбитое на страницы представление о JSP?
Например, это - мой запрос и набор результатов:
pst = con.prepareStatement("select userName, job, place from contact");
rs = pst.executeQuery();
В документах указано, что существует 4 различных механизмов места хранения. Модуль FallbackStorage
выполняет запись в сеанс.
Это, как правило, не безопасно, независимо от того, хранится ли внутренняя последовательность строк в памяти непрерывно или нет. Кроме непрерывности, может быть много других деталей реализации, связанных с тем, как управляемая последовательность хранится объектом std:: string
.
Реальной практической проблемой с этим может быть следующее. Управляемая последовательность std:: string
не должна храниться как строка с нулевым окончанием. Однако на практике многие (большинство?) реализации выбирают избыточный размер внутреннего буфера на 1 и сохраняют последовательность как строку с нулевым окончанием в любом случае, потому что это упрощает реализацию метода c _ str ()
: просто верните указатель на внутренний буфер, и вы закончите.
Код, процитированный в вашем вопросе, не пытается обнулить данные, копируется во внутренний буфер. Вполне возможно, он просто не знает, необходимо ли нулевое прекращение для этой реализации std:: Последовательности
. Вполне возможно, что он полагается на внутренний буфер, заполняемый нулями после вызова resize
, так что дополнительный символ, выделенный для ограничителя нуля реализацией, удобно предварительно устанавливается равным нулю. Все это - деталь реализации, означающая, что этот прием зависит от некоторых довольно хрупких предположений.
Другими словами, в некоторых реализациях, вероятно, придется использовать strcpy
, а не memcpy
, чтобы принудительно ввести данные в управляемую последовательность. В некоторых других реализациях необходимо использовать memcpy
, а не strcpy
.
Для запуска необходимо добавить один или два дополнительных параметра запроса в JSP: firstrow
и (необязательно) rowcount
. Значение rowcount
также можно оставить и полностью определить на стороне сервера.
Затем добавьте группу кнопок пейджинга в JSP: кнопка next должна дать команду Servlet
увеличить значение firstrow
на rowcount
. Кнопка предыдущего должна явно уменьшить значение первой строки
до значения числа строк
. Не забудьте правильно обрабатывать отрицательные значения и переполнения! Это можно сделать с помощью SELECT count (id)
.
Затем запустите определенный SQL-запрос для получения подсписка результатов. Однако точный синтаксис SQL зависит от используемой базы данных. В MySQL и PostgreSQL легко с предложениями LIMIT
и OFFSET
:
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;
}
В Oracle вам нужен подзапрос с предложением rownum
, который должен выглядеть следующим образом:
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;
}
В DB2 вам нужна функция OLAP строка _ номер ()
для этого:
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;
}
Я не делаю MSSQL, но он синтаксически похож на DB2. См. также в этом разделе .
Наконец, просто представьте сублист на странице JSP обычным способом с 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>
Обратите внимание, что некоторые могут предложить SELECT
всей таблицы и сохранить List < Contact >
в области сеанса и использовать List # subList ()
для разбиения на страницы. Но это далеко от эффективного использования памяти с тысячами строк и несколькими параллельными пользователями.
Для тех, кто заинтересован в подобном ответе в контексте JSF/MySQL, используя компонент h: dataTable
, вы можете найти эту статью полезной. Он также содержит некоторые полезные языковые агностические математики, чтобы получить «Google-подобные» pagination красиво работать.
Вот пара вещей, которые вы можете сделать:
Определите общее количество страниц в зависимости от количества элементов.
Отображение элементов на основе смещения, которое вы определили (отображение только начиная с пункта 48)
=======
Это ваш основной подход. Вы можете настроить его следующим образом:
Ищите шаблон списка значений и применяйте его. Обычно это лучший способ справиться с такими вещами.