批量分页

2024-01-01 09:49:07 浏览数 (2)

再也无需前思后想,一切岂非已然过往。——《且听风吟》

今天分享一个装一个分批分页,传入页码、分页条数,然后查询分页条数 1条数据,这里的 1是为了判断还有下一页数据,然后查询到后,再按照传入的lambda条件筛选,筛选完后的数据添加进集合,添加到集合后如果满足当前分页所需条数,就返回数据

这里需要做一个容错,当时间超过后直接返回,避免传入的lambda predicate一直为false导致死循环

代码语言:javascript复制
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.experimental.UtilityClass;
import org.dromara.streamquery.stream.core.stream.Steam;

import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;

@UtilityClass
public final class PageUtil {

    public static <T> Page<T> batchFlow(Page<T> page, BiFunction<Long, Long, List<T>> queryFunc,
                                        Function<List<T>, Predicate<T>> predFun, int timeout) {
        var pageNum = page.getCurrent();
        var pageSize = page.getSize();
        List<T> results = new ArrayList<>();
        Predicate<T> predicate = predFun.apply(results);
        page.setRecords(results);
        var startTime = System.currentTimeMillis();
        while (results.size() < pageSize && (timeout < 0 || (System.currentTimeMillis() - startTime) < timeout)) {
            var items = queryFunc.apply(pageNum, pageSize   1);
            boolean noNextPage = items.size() < pageSize   1;
            var filteredItems = Steam.of(items).filter(predicate).toList();
            page.setTotal(noNextPage ? (page.getCurrent() - 1) * page.getSize()   filteredItems.size() :
                    page.getCurrent() * page.getSize()   1);
            for (T item : filteredItems) {
                if (results.size() < pageSize) {
                    results.add(item);
                } else {
                    // Enough items for this page, extra items indicate there's a next page
                    return page;
                }
            }
            if (noNextPage) {
                return page;
            }
            // Next page
            pageNum  ;
        }
        return page;
    }

}

测试用例:

代码语言:javascript复制
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.dromara.streamquery.stream.core.collection.Lists;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.stream.Stream;

/**
 * PageUtilTest
 *
 * @author VampireAchao<achao @ hutool.cn>
 */
class PageUtilTest {

    @Test
    void batchPagingTest() {
        Page<Object> page = PageUtil.batchFlow(new Page<>(1, 10),
                (current, size) -> {
                    return new ArrayList<>();
                }, list -> i -> false, 100);
        Assertions.assertTrue(page.getRecords().isEmpty());

        Page<Long> page1 = PageUtil.batchFlow(new Page<>(1, 10), (current, size) -> {
            return Stream.iterate((current - 1) * size   1, i -> i <= current * size, i ->   i).toList();
        }, list -> i -> i % 2 == 0, -1);
        Assertions.assertEquals(Lists.of(2L, 4L, 6L, 8L, 10L, 12L, 14L, 16L, 18L, 20L), page1.getRecords());

        Page<Long> page2 = PageUtil.batchFlow(new Page<>(2, 10), (current, size) -> {
            return Stream.iterate(1L, i ->   i).limit(9).toList();
        }, list -> i -> true, -1);
        Assertions.assertEquals(19, page2.getTotal());
        Assertions.assertEquals(Lists.of(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L), page2.getRecords());

    }

}

0 人点赞