java代码实现分页功能技术详解

以下示例展示了如何使用Java编写一个简单的分页功能,以及如何在Web应用程序中使用Spring和Thymeleaf框架来实现它。当然,实际应用中还需要考虑更多的因素,例如如何处理排序和过滤,以及如何处理大量数据的性能问题等。

以下是Java代码实现分页功能的示例:

import java.util.List;

public class PaginationUtil {
    
    public static <T> List<T> getPage(List<T> list, int pageNumber, int pageSize) {
        int startIndex = (pageNumber - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, list.size());
        return list.subList(startIndex, endIndex);
    }
    
    public static int getTotalPages(List<?> list, int pageSize) {
        return (int) Math.ceil((double) list.size() / pageSize);
    }
}

在这个示例中,getPage()方法接收一个List对象、页码和每页的大小作为参数,并返回一个包含所请求页码的元素的子列表。 getTotalPages()方法计算给定列表的总页数。

以下是如何使用这个示例代码的示例:

import java.util.ArrayList;
import java.util.List;

public class Main {
    
    public static void main(String[] args) {
        List<String> fruits = new ArrayList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Orange");
        fruits.add("Pineapple");
        fruits.add("Strawberry");
        
        int pageSize = 2;
        int pageNumber = 2;
        
        List<String> page = PaginationUtil.getPage(fruits, pageNumber, pageSize);
        int totalPages = PaginationUtil.getTotalPages(fruits, pageSize);
        
        System.out.println("Page " + pageNumber + " of " + totalPages + ": " + page);
    }
}

在这个示例中,我们创建了一个包含5个水果的List对象,并且我们想要每页显示2个水果。 我们请求第2页,并将返回的结果存储在一个名为“page”的列表中。我们还计算了总页数,它将是3页。 最后,我们将页码和结果输出到控制台上。

输出:

Page 2 of 3: [Orange, Pineapple]

如果要在Web应用程序中实现分页功能,通常需要在控制器(Controller)层和视图(View)层之间传递一个包含当前页、每页大小、总页数和要显示的元素的Page对象。以下是一个简单的示例:

import java.util.List;

public class Page<T> {
    
    private List<T> elements;
    private int pageNumber;
    private int pageSize;
    private int totalPages;
    
    public Page(List<T> elements, int pageNumber, int pageSize, int totalPages) {
        this.elements = elements;
        this.pageNumber = pageNumber;
        this.pageSize = pageSize;
        this.totalPages = totalPages;
    }
    
    public List<T> getElements() {
        return elements;
    }
    
    public int getPageNumber() {
        return pageNumber;
    }
    
    public int getPageSize() {
        return pageSize;
    }
    
    public int getTotalPages() {
        return totalPages;
    }
}

这个Page类包含了当前页的元素(通过elements属性)、当前页码(通过pageNumber属性)、每页大小(通过pageSize属性)和总页数(通过totalPages属性)。它还提供了适当的getter方法以便在控制器和视图之间传递信息。

以下是一个使用该Page类的控制器示例:

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.ArrayList;
import java.util.List;

@Controller
public class FruitController {
    
    @GetMapping("/fruits")
    public String showFruits(
            @RequestParam(name = "page", defaultValue = "1") int pageNumber,
            @RequestParam(name = "size", defaultValue = "5") int pageSize,
            Model model) {
        
        List<String> fruits = new ArrayList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Orange");
        fruits.add("Pineapple");
        fruits.add("Strawberry");
        
        int totalFruits = fruits.size();
        int totalPages = (int) Math.ceil((double) totalFruits / pageSize);
        List<String> page = PaginationUtil.getPage(fruits, pageNumber, pageSize);
        
        Page<String> fruitPage = new Page<>(page, pageNumber, pageSize, totalPages);
        model.addAttribute("fruitPage", fruitPage);
        
        return "fruit-list";
    }
}

在这个示例中,我们定义了一个控制器方法,它将分页后的水果列表作为参数传递给视图。我们使用Spring框架中的@RequestParam注解来接收页面请求中传递的页码和每页大小参数。然后,我们计算总页数和当前页的元素列表,并将它们放入一个Page对象中。最后,我们将Page对象作为模型(Model)属性传递给视图。

以下是一个使用Thymeleaf模板引擎的视图示例:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Fruits</title>
</head>
<body>
    <h1>Fruits</h1>
    <table>
        <tr>
            <th>Name</th>
        </tr>
        <tr th:each="fruit : ${fruitPage.elements}">
            <td th:text="${fruit>
 </td>
</tr>
</table>
<div th:if="${fruitPage.totalPages > 1}">
<ul>
<li th:class="${fruitPage.pageNumber == 1} ? disabled : ''">
<a th:href="@{/fruits(page=1,size=${fruitPage.pageSize})}">&laquo;</a>
</li>
<li th:class="${fruitPage.pageNumber == 1} ? disabled : ''">
<a th:href="@{/fruits(page=${fruitPage.pageNumber - 1},size=${fruitPage.pageSize})}">&lt;</a>
</li>
<li th:each="page : ${#numbers.sequence(1, fruitPage.totalPages)}">
<a th:href="@{/fruits(page=${page},size=${fruitPage.pageSize})}" 
th:class="${page == fruitPage.pageNumber} ? active : ''"
th:text="${page}"></a>
</li>
<li th:class="${fruitPage.pageNumber == fruitPage.totalPages} ? disabled : ''">
<a th:href="@{/fruits(page=${fruitPage.pageNumber + 1},size=${fruitPage.pageSize})}">&gt;</a>
</li>
<li th:class="${fruitPage.pageNumber == fruitPage.totalPages} ? disabled : ''">
<a th:href="@{/fruits(page=${fruitPage.totalPages},size=${fruitPage.pageSize})}">&raquo;</a>
</li>
</ul>
</div>
</body>
</html>

在这个视图中,我们首先使用Thymeleaf的th:each属性遍历Page对象中的元素列表,并将它们展示在一个HTML表格中。接下来,我们使用Thymeleaf的条件语句和表达式来控制分页导航栏的显示。我们使用了一个ul标签来展示页码列表,并为当前页添加了一个active样式类。我们还使用了一些样式类来禁用第一页和最后一页的链接,以及禁用前一页和后一页的链接(当它们无法使用时)。