【问题标题】:Pagination and sorting in Spring MVC 4Spring MVC 4 中的分页和排序
【发布时间】:2016-02-23 19:09:38
【问题描述】:

我正在使用 spring mvc 4、thymeleaf 和 mysql(jdbc 不使用 hibernate 或 JPA)构建一个 Web 应用程序。我正在尝试进行分页和排序,但我认为我在理解它时遇到了问题。

当我使用 spring mvc 搜索分页时,我只能找到 PagedListHolder 和 MutableSortDefinition,但我认为这不是正确的方法,因为它会为每个请求加载服务器内存中所有数据的列表,是对吗?如果是这样,那么鉴于有数十万条记录(一个多月的房地产广告,每天将近 2500 个广告),实现分页和排序的最佳方法是什么

那么,有人可以举一个真实的例子来说明如何以一种可用于大数据应用程序的方式实现分页和排序吗?

【问题讨论】:

  • 如果您希望您的数据在表格中表示,我可以建议您Dandelion Datatables。这个框架(建立在 JQuery Datatable 之上)有很多可以使用的特性(比如分页、排序等)。由于“服务器端处理”功能,它适用于大数据。我们用它来代表超过一百万个条目,一切都很好。我写的是关于客户端的,顺便说一句:)
  • Thx enigo .. 我检查了它,它看起来不错且易于使用 .. 所以它在具有百万条目的高流量下运行良好(在页面加载速度、内存和 CPU 消耗方面)? .. 也出于好奇,你知道 pagedListHolder 是如何工作的吗?我的意思是它是否真的为每个用户加载了内存中的所有对象(因为它通常保存在会话属性中)?我的意思是,如果您有数千条记录(甚至不是数万条)并且有数千个并发用户和会话,那么服务器会因过载而爆炸,对吗?
  • 是的,它的工作速度与您的服务器端能够发回结果的速度一样快。用于此类任务的 Datatable 的关键特性是“服务器端处理”。基本上,它只允许您获取一个特定页面的条目,而不是数万个。但另一方面,用户执行的每个操作(选择下一页\上一页、排序等)都是在服务器端完成的。所以,任务是让服务器工作得非常快。不幸的是,我对 pagedListHolder 一无所知,根据谷歌搜索结果,它似乎不是很受欢迎:)
  • 我很好奇你有没有尝试过我的建议?)

标签: sorting spring-mvc pagination spring-jdbc


【解决方案1】:

试试这个方法

  • 带有参数“PageRequest()”的findAll方法提供服务器端分页
  • 有两种方法

    PageRequest(int page, int size)

    PageRequest(int page, int size, Direction direction, String...属性)

查看

<table class="table">
            <thead style="background-color: #eee">
                <tr>
                    <td>Dispature</td>
                    <td>Service</td>
                    <td>Host</td>
                    <td>Value</td>
                </tr>
            </thead>
            <tbody>
                <tr ng-repeat="x in app.metricsList">
                    <td>{{x.dispature}}</td>
                    <td>{{x.service}}</td>
                    <td>{{x.host}}</td>
                    <td>{{x.value}}</td>
                </tr>
            </tbody>
        </table>
        <div align="center">
            <uib-pagination items-per-page="app.itemPerPage" num-pages="numPages"
                total-items="app.totalItems" boundary-link-numbers="true"
                ng-model="app.currentPage" rotate="false" max-size="app.maxSize"
                class="pagination-sm" boundary-links="true"
                ng-click="app.getPagableRecords()"></uib-pagination>        

            <div style="float: right; margin: 15px">
                <pre>Page: {{app.currentPage}} / {{numPages}}</pre>
            </div>          
        </div>

Js 控制器

app.controller('AllEntryCtrl',['$scope','$http','$timeout','$rootScope', function($scope,$http,$timeout,$rootScope){

    var app = this;
    app.currentPage = 1;
    app.maxSize = 5;
    app.itemPerPage = 5;
    app.totalItems = 0;

    app.countRecords = function() {
        $http.get("countRecord")
        .success(function(data,status,headers,config){
            app.totalItems = data;
        })
        .error(function(data,status,header,config){
            console.log(data);
        });
    };

    app.getPagableRecords = function() {
        var param = {
                page : app.currentPage,
                size : app.itemPerPage  
        };
        $http.get("allRecordPagination",{params : param})
        .success(function(data,status,headers,config){
            app.metricsList = data.content;
        })
        .error(function(data,status,header,config){
            console.log(data);
        });
    };

    app.countRecords();
    app.getPagableRecords();

}]);

控制器

@RestController
public class HomeController {

@Autowired
private HomeRepo repo;

  @RequestMapping(value = "allRecordPagination", method = RequestMethod.GET)
    public Page<Metrics> getAllRecordPagination(@RequestParam("page") int page, @RequestParam("size") int size){
        return repo.findAll(new PageRequest(page-1, size));
    }
}

存储库

@Repository
    public interface HomeRepo extends JpaRepository<Table, String>{
}

【讨论】:

    【解决方案2】:

    为了扩展我的 cmets,我想分享一些代码 sn-ps 来展示使用 Thymeleaf 实现 Dandelion Datatables 是多么容易。 所以,在客户端我有两个文件:用于表格渲染的 html

    ....    
    <table id="dTable" class="display dataTable" dt:table="true">
        <thead>
            <tr>
               <th th:text="#{requestId}"></th>
               <th th:text="#{clientTime}"></th>
               <th th:text="#{requestDate}"></th>
               <th th:text="#{receiver}"></th>
            </tr>
        </thead>
    </table>
    ....
    

    和用于表初始化的js

    $(document).ready(function() {
        $('#dTable').DataTable( {
            ajax: { url: "/bhost/dtable_list"},
            processing: true,
            serverSide: true,
            bFilter: false,
            columns: [
                { data: "requestId" },
                { data: "clientTime" },
                { data: "requestDate" },
                { data: "receiver", orderable: false },
            ],
           lengthMenu: [50, 100, 200, 500],
           language: {
             thousands: " "
          }
        } );
    } );
    

    尽管可以只在 html 中配置蒲公英数据表,但我更喜欢使用 JQuery 方式来完成它,因为它更灵活。

    在服务器端,我们使用我们自己创建的数据库访问层(共享它不是很有用)和蒲公英DatatablesCriterias 类来获取表的当前状态(当前页面索引、页面长度、选择的排序列等)

        Controller
    ....
            @RequestMapping(value = "/dtable_list")
            @ResponseBody
            public DatatablesResponse<DataDTO> getTableData(HttpServletRequest request) {
                HttpSession session = request.getSession();
                DataModel model = (DaatModel) session.getAttribute(MODEL_NAME);
                DatatablesCriterias criterias = DatatablesCriterias.getFromRequest(request);
                List<DataDTO> list = finder.getForCriterias(model, timeZoneOffset, criterias);
                Long totalCount = model.getCount();
                return DatatablesResponse.build(new DataSet<>(list, totalCount, totalCount), criterias);
            }
    ....
    

    这里的关键特性是 DatatablesCriterias,因为它包含检索与用户选择相关的条目所需的所有数据。 差不多就是这样(我猜除了配置部分)

    【讨论】:

      【解决方案3】:

      这是一个使用 SpringBoot 和 Thymeleaf 模板进行分页的示例,试试吧! clone it and run it

      【讨论】:

        猜你喜欢
        • 2015-11-18
        • 2015-08-17
        • 2013-04-08
        • 2014-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多