Spring MVC 4中的分页和排序

时间:2021-01-30 14:30:31

I'm building a web app using spring mvc 4, thymeleaf and mysql (jdbc is used not hibernate or JPA) .. and I'm trying to do pagination and sorting, but I think I have a problem understanding it.

我正在使用spring mvc 4,thymeleaf和mysql构建一个web应用程序(jdbc不用于hibernate或JPA)..我正在尝试进行分页和排序,但我认为我有一个问题需要理解它。

When I search for pagination using spring mvc all I can find is PagedListHolder and MutableSortDefinition, but I don't think it's the right way to go since it will load a list of all the data in server memory for each request, is that right? and if so, then what is the best way to implement pagination and sorting given that there are hundreds of thousands of records (advertisements for real-estate over a month, with almost 2500 ads a day)

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

So, could someone put a real-world example of how to implement pagination and sorting in a way that can be used with large data apps?

那么,是否有人能够以一种可以与大数据应用程序一起使用的方式实现如何实现分页和排序的真实示例?

3 个解决方案

#1


0  

In order to expand my comments I want to share some code snippets to show how easy it is to implement Dandelion Datatables with Thymeleaf. So, on the client side I have two files: html for table render

为了扩展我的评论,我想分享一些代码片段,以展示使用Thymeleaf实现蒲公英数据表是多么容易。所以,在客户端我有两个文件:用于表格渲染的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>
....

and js for table initialization

和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: " "
      }
    } );
} );

Even though it's possible to configure dandelion datatables only in html I prefer to use JQuery way to do it, since it's more flexible.

尽管只能在html中配置蒲公英数据表,但我更喜欢使用JQuery方法来实现它,因为它更灵活。

On the server side we used our own created database access layer (not quite useful to share it) and dandelion DatatablesCriterias class to get current state of table (current page index, page length, selected sorted column etc.)

在服务器端,我们使用自己创建的数据库访问层(分享它并不十分有用)和蒲公英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);
        }
....

The key feature here is DatatablesCriterias, since it contains all necessary data to retrieve entries that correlate with user selection. And that's pretty much it (Except configuration part, I guess)

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

#2


0  

Try this way :

试试这种方式:

  • findAll method with argument "PageRequest()" provides the server side pagination
  • 带参数“PageRequest()”的findAll方法提供服务器端分页

  • there are two methods

    有两种方法

    PageRequest(int page, int size)

    PageRequest(int page,int size)

    PageRequest(int page, int size, Direction direction, String... properties)

    PageRequest(int page,int size,Direction direction,String ... properties)

View :

<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 Controller :

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();

}]);

Controller :

@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 :

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

#3


0  

this is an example of pagination with SpringBoot and Thymeleaf templates, try it!! clone it and run it

这是一个分享SpringBoot和Thymeleaf模板的例子,试一试!!克隆它并运行它

#1


0  

In order to expand my comments I want to share some code snippets to show how easy it is to implement Dandelion Datatables with Thymeleaf. So, on the client side I have two files: html for table render

为了扩展我的评论,我想分享一些代码片段,以展示使用Thymeleaf实现蒲公英数据表是多么容易。所以,在客户端我有两个文件:用于表格渲染的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>
....

and js for table initialization

和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: " "
      }
    } );
} );

Even though it's possible to configure dandelion datatables only in html I prefer to use JQuery way to do it, since it's more flexible.

尽管只能在html中配置蒲公英数据表,但我更喜欢使用JQuery方法来实现它,因为它更灵活。

On the server side we used our own created database access layer (not quite useful to share it) and dandelion DatatablesCriterias class to get current state of table (current page index, page length, selected sorted column etc.)

在服务器端,我们使用自己创建的数据库访问层(分享它并不十分有用)和蒲公英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);
        }
....

The key feature here is DatatablesCriterias, since it contains all necessary data to retrieve entries that correlate with user selection. And that's pretty much it (Except configuration part, I guess)

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

#2


0  

Try this way :

试试这种方式:

  • findAll method with argument "PageRequest()" provides the server side pagination
  • 带参数“PageRequest()”的findAll方法提供服务器端分页

  • there are two methods

    有两种方法

    PageRequest(int page, int size)

    PageRequest(int page,int size)

    PageRequest(int page, int size, Direction direction, String... properties)

    PageRequest(int page,int size,Direction direction,String ... properties)

View :

<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 Controller :

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();

}]);

Controller :

@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 :

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

#3


0  

this is an example of pagination with SpringBoot and Thymeleaf templates, try it!! clone it and run it

这是一个分享SpringBoot和Thymeleaf模板的例子,试一试!!克隆它并运行它