Как преобразовать объект Resultset в разбитый на страницу вид в JSP?
Например, это мой запрос и набор результатов:
pst = con.prepareStatement("select userName, job, place from contact");
rs = pst.executeQuery();
Как преобразовать объект Resultset в разбитый на страницу вид в JSP?
Например, это мой запрос и набор результатов:
pst = con.prepareStatement("select userName, job, place from contact");
rs = pst.executeQuery();
Для начала вам нужно добавить один или два дополнительных параметра запроса в JSP: firstrow
и (необязательно) rowcount
. Количество rowcount
также может быть опущено и полностью определено на стороне сервера.
Затем добавить кучу кнопок пейджинговой к JSP: следующая кнопка должна проинструктировать Servlet
, чтобы увеличить значение firstrow
со значением rowcount
. Предыдущая кнопка, очевидно, должна firstrow
значение 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 row_number()
для этого:
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()
для List#subList()
на страницы. Но это далеко не эффективно для памяти с тысячами строк и несколькими одновременными пользователями.
Для тех, кто интересуется подобным ответом в контексте JSF/MySQL с использованием компонента h:dataTable
, эта статья может оказаться полезной. Он также содержит несколько полезных не зависящих от языка математических выражений, позволяющих удобно работать с "Google-подобной" нумерацией страниц.
Этот пример Oracle неверен.
Да, во внешнем select имеют хорошие значения ROWNUM, но это все еще псевдо столбцы, поэтому мы не можем использовать BETWEEN на нем. Нам нужен еще один выбор.
Правильный код sql:
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
Товарищи, используя сплошную строку sql и класс Statement SLOWOW. Oracle должен анализировать ваш SQL каждый раз, когда вы его выполняете.
//Slooow example
Satement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select * from my_table where id = 11");
Используйте параметры PreparedStatement и привязки.
//Faster example
PreparedStatement ps = conn.getPrepareStatement("select * from my_table where id = ?");
ps.setInt(1, 11);
И самое быстрое решение помещает ваш sql в хранимую процедуру oracle и использует CallableStatement для его вызова.
//Fastest example
CallableStatement cs = conn.prepareCall("{? = call my_plsql_function(?)}");
cs.setInt(1, 11);
Вот несколько вещей, которые вы можете сделать:
Определите общее количество страниц на основе количества элементов.
Отобразите свои объекты на основе установленного вами смещения (только отображение начинается с позиции 48)
=======
Это ваш основной подход. Вы можете настроить его следующим образом:
это не позволит мне добавить комментарий, поэтому, пожалуйста, не считайте это ответом. Я просто хотел разъяснений по поводу поста Пиюша выше. Где у вас есть ai.add(sdata); и вернуть ai, это должно было быть "al" из класса StudentList?
Посмотрите на шаблон списка значений и примените его. Это обычно лучший способ справиться с такими вещами.
Вы можете использовать displaytag для paigination или resultset, но u загружать некоторый файл jar из файла disattag
сначала вы создаете один сервлет StudentList.java
public class StudentList extends HttpServlet
{ public void service (запрос HttpServletRequest, ответ HttpServletResponse) вызывает 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
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;
}