Разбиение на страницы большими SQL-результатов


Он чувствует, как нумерация страниц является одним из самых обсуждаемых вопросов в сети, которая всегда заканчивается некоторые быстрые и грязные хаки о том, как вставить. Я хочу, чтобы вставить большой результирующий набор из запроса SQL на сайте, где я использовать Spring-JDBC для выполнения запросов и Displaytag для отображения. Я думал об этом некоторое время, и в конце концов пришла к реализации ResultSetExtractor такой:

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.displaytag.pagination.PaginatedList;
import org.displaytag.properties.SortOrderEnum;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ColumnMapRowMapper;
import org.springframework.jdbc.core.ResultSetExtractor;

public class PaginatingResultMapExtractor implements
        ResultSetExtractor<PaginatedList>
{
    private final int page;
    private final int pageSize;
    private final String sortColumn;
    private final SortOrderEnum sortDirection;

    public PaginatingResultMapExtractor(int page, int pageSize,
            String sortColumn, SortOrderEnum sortDirection)
    {
        super();
        this.page = page;
        this.pageSize = pageSize;
        this.sortColumn = sortColumn;
        this.sortDirection = sortDirection;
    }

    @Override
    public PaginatedList extractData(ResultSet rs) throws SQLException,
            DataAccessException
    {
        final ColumnMapRowMapper mapper = new ColumnMapRowMapper();
        final List<Object> result = new ArrayList<Object>(
                pageSize);
        int i;
        for (i = 0; rs.next(); ++i)
        {
            if (i > (page - 1) * pageSize
                    && i < page * pageSize)
                result.add(mapper.mapRow(rs, i));
        }
        return new PaginatedListImpl<Object>(result, i,
                pageSize, page, sortColumn, sortDirection);
    }
}

PaginatedListImpl просто хранит ценности, которые я передаю в конструктор и делает их доступными с геттер-метода, выполняя требования PaginatedList интерфейса по displaytag.

Я могу использовать это, просто позвонив по телефону:

jdbcTemplate.query("select ... from ...", new PaginatingResultMapExtractor(page, pageSize, sortColumn, sortDirection));

По крайней мере, это решение является очень простым в использовании. Но ведь я должен перебрать весь результирующий набор. Может ли этот код быть улучшено?



17784
7
задан 14 июля 2011 в 09:07 Источник Поделиться
Комментарии
1 ответ

Пагинация должна быть выполнена сервером базы данных, где это применимо. Нет смысла передавать данные по проводу, если он не используется, так что вы должны думать о делаете, проходит в свой номер страницы и считать переменные в запрос или предпочтительнее хранимую процедуру и использовать SQL для выбора подмножества данных, которые вы хотите. Есть в большинстве вариантов языка SQL для этого конструкций SQL.

Вот пример с использованием MySQL:

SELECT `field1`, `field2` from `mycatalog` LIMIT start, (start + cnt)

И что-то похожее с SQL сервером:

WITH #set AS (SELECT [Field1], [Field2], ROW_NUMER() OVER (ORDER BY [Field1]) AS [Index] FROM [MyDatabase])
SELECT [Field1], [Field2] FROM #set WHERE [INDEX] BETWEEN @start AND (@start + @count)

8
ответ дан 14 июля 2011 в 07:07 Источник Поделиться