2016-02-23 5 views
0

Я создаю веб-приложение с использованием весны mvc 4, тимелеафа и mysql (jdbc используется не в спящем режиме или JPA) .. и я пытаюсь сделать разбиение на страницы и сортировку, но я думаю У меня проблема с пониманием этого.Разбиение на страницы и сортировка по весне MVC 4

Когда я ищу разбивку на страницы с использованием весны mvc, все, что я могу найти, это PagedListHolder и MutableSortDefinition, но я не думаю, что это правильный путь, поскольку он будет загружать список всех данных в памяти сервера для каждого запроса, это правильно? и если да, то каков наилучший способ реализации разбивки на страницы и сортировки, учитывая, что есть сотни тысяч записей (реклама за месяц в месяц с почти 2500 объявлениями в день)

Итак, может кто-то положить реальный пример того, как реализовать разбиение на страницы и сортировку таким образом, который можно использовать с большими приложениями для данных?

+1

Если вы хотите, чтобы ваши данные были представлены в таблице, я могу предложить вам [Dandelion Datatables] (http://dandelion.github.io/components/datatables). Эта структура (построенная на JQuery Datatable) имеет множество функций, готовых к использованию (например, разбиение на страницы, сортировка и т. Д.). И он хорошо работает для больших данных из-за «обработки на стороне сервера». Мы использовали его для представления более миллиона записей, и все работает просто отлично. Я написал о стороне клиента, BTW :) – Enigo

+0

Thx enigo .. Я проверил его, и он выглядит хорошо и прост в использовании .. поэтому он работает хорошо при высоком трафике с миллионными записями (в вопросах скорости загрузки страницы, памяти и потребление процессора)? .. также из любопытства, знаете ли вы, как работает pagedListHolder? Я имею в виду, действительно ли он загружает весь объект в память для каждого пользователя (поскольку он обычно сохраняется в атрибуте сеанса)? Я имею в виду, если у вас есть тысячи записей (даже не десятки тысяч), и у вас есть тысячи одновременных пользователей и сеансов, сервер будет взлетать от перегрузки, верно? –

+0

Да, он работает так же быстро, как ваша серверная сторона может отправлять результаты назад. Ключевой особенностью Datatable для таких задач является «обработка на стороне сервера». В основном это позволяет вам получать записи только для одной конкретной страницы, а не десятки тысяч. Но с другой стороны каждый пользователь действия выполняет (выбор следующей страницы \ prev, сортировка и т. Д.) Выполняется на стороне сервера. Таким образом, задача состоит в том, чтобы заставить сервер работать очень быстро. К сожалению, я ничего не знаю о pagedListHolder, и, похоже, это не очень популярно, согласно результатам google :) – Enigo

ответ

0

Чтобы развернуть мои комментарии, я хочу поделиться некоторыми фрагментами кода, чтобы показать, насколько легко реализовать Dandelion Datatables с 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> 
.... 

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

Несмотря на то, что можно настроить одуванчик DataTables только в 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, поскольку он содержит все необходимые данные для извлечения записей, которые коррелируют с выбором пользователя. И это в значительной степени это (за исключением конфигурации части, я думаю)

0

Попробуйте этот путь :

  • метод FindAll с аргументом "PageRequest()" предоставляет на стороне сервера пагинацию
  • существует два метода:

    PageRequest (int, int size)

    PageRequest (int page, int size, Направление, Строка ...свойства)

Посмотреть :

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

@Repository 
    public interface HomeRepo extends JpaRepository<Table, String>{ 
} 
Смежные вопросы