Add pagination to Orders and Messages Serivces

This commit is contained in:
parent 1874d96ed7
commit 745795e7b7
10 changed files with 207 additions and 10 deletions

Binary file not shown.

View File

@ -0,0 +1,117 @@
package com.example.demo.core.api;
import java.util.ArrayList;
import java.util.List;
// DTO для страниц (Пагинация)
public class PageDto<D> {
// Список элементов
private List<D> items = new ArrayList<>();
// Количество элементов
private int itemsCount;
// Текущая страница
private int currentPage;
// Текущий размер
private int currentSize;
// Общее количество страниц
private int totalPages;
// Общее количество элементов
private long totalItems;
// Первая страница
private boolean isFirst;
// Последняя страница
private boolean isLast;
// Есть следующая старница
private boolean hasNext;
// Есть предыдущая страница
private boolean hasPrevious;
public List<D> getItems() {
return items;
}
public void setItems(List<D> items) {
this.items = items;
}
public int getItemsCount() {
return itemsCount;
}
public void setItemsCount(int itemsCount) {
this.itemsCount = itemsCount;
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getCurrentSize() {
return currentSize;
}
public void setCurrentSize(int currentSize) {
this.currentSize = currentSize;
}
public int getTotalPages() {
return totalPages;
}
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
}
public long getTotalItems() {
return totalItems;
}
public void setTotalItems(long totalItems) {
this.totalItems = totalItems;
}
public boolean isFirst() {
return isFirst;
}
public void setFirst(boolean isFirst) {
this.isFirst = isFirst;
}
public boolean isLast() {
return isLast;
}
public void setLast(boolean isLast) {
this.isLast = isLast;
}
public boolean isHasNext() {
return hasNext;
}
public void setHasNext(boolean hasNext) {
this.hasNext = hasNext;
}
public boolean isHasPrevious() {
return hasPrevious;
}
public void setHasPrevious(boolean hasPrevious) {
this.hasPrevious = hasPrevious;
}
}

View File

@ -0,0 +1,26 @@
package com.example.demo.core.api;
import java.util.function.Function;
import org.springframework.data.domain.Page;
// Преобразование в DTO страниц (Пагинация)
public class PageDtoMapper {
private PageDtoMapper() {
}
public static <D, E> PageDto<D> toDto(Page<E> page, Function<E, D> mapper) {
final PageDto<D> dto = new PageDto<>();
dto.setItems(page.getContent().stream().map(mapper::apply).toList());
dto.setItemsCount(page.getNumberOfElements());
dto.setCurrentPage(page.getNumber());
dto.setCurrentSize(page.getSize());
dto.setTotalPages(page.getTotalPages());
dto.setTotalItems(page.getTotalElements());
dto.setFirst(page.isFirst());
dto.setLast(page.isLast());
dto.setHasNext(page.hasNext());
dto.setHasPrevious(page.hasPrevious());
return dto;
}
}

View File

@ -8,6 +8,9 @@ public class Constants {
// Базовый префикс REST-API // Базовый префикс REST-API
public static final String API_URL = "/api/1.0"; public static final String API_URL = "/api/1.0";
// Размер страницы пагинации
public static final String DEFAULT_PAGE_SIZE = "5";
private Constants() { private Constants() {
} }
} }

View File

@ -10,8 +10,11 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.example.demo.core.api.PageDto;
import com.example.demo.core.api.PageDtoMapper;
import com.example.demo.core.configuration.Constants; import com.example.demo.core.configuration.Constants;
import com.example.demo.messages.model.MessageEntity; import com.example.demo.messages.model.MessageEntity;
import com.example.demo.messages.service.MessageService; import com.example.demo.messages.service.MessageService;
@ -47,10 +50,11 @@ public class MessageController {
// Получить все элементы // Получить все элементы
@GetMapping @GetMapping
public List<MessageDto> getAll(@PathVariable(name = "user") Long userId) { public PageDto<MessageDto> getAll(
return messageService.getAll(userId).stream() @PathVariable(name = "user") Long userId,
.map(this::toDto) @RequestParam(name = "page", defaultValue = "0") int page,
.toList(); @RequestParam(name = "size", defaultValue = Constants.DEFAULT_PAGE_SIZE) int size) {
return PageDtoMapper.toDto(messageService.getAll(userId, page, size), this::toDto);
} }
// Получить элемент по идентификатору // Получить элемент по идентификатору

View File

@ -3,6 +3,8 @@ package com.example.demo.messages.repository;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import com.example.demo.messages.model.MessageEntity; import com.example.demo.messages.model.MessageEntity;
@ -12,6 +14,12 @@ public interface MessageRepository extends CrudRepository<MessageEntity, Long> {
// Получить сообщение по пользователю и идентификатору // Получить сообщение по пользователю и идентификатору
Optional<MessageEntity> findOnyByUserIdAndId(Long userId, Long id); Optional<MessageEntity> findOnyByUserIdAndId(Long userId, Long id);
// Получить список всех сообщений (с пагинацией)
Page<MessageEntity> findAll(Pageable pageable);
// Получить список сообщений по пользователю // Получить список сообщений по пользователю
List<MessageEntity> findByUserId(Long userId); List<MessageEntity> findByUserId(Long userId);
// Получить список сообщений по пользователю (с пагинацией)
Page<MessageEntity> findByUserId(Long userId, Pageable pageable);
} }

View File

@ -3,6 +3,8 @@ package com.example.demo.messages.service;
import java.util.List; import java.util.List;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -39,6 +41,19 @@ public class MessageService {
} }
} }
// Получить все элементы или по заданному фильтру (с пагинацией)
@Transactional(readOnly = true)
public Page<MessageEntity> getAll(Long userId, int page, int size) {
final PageRequest pageRequest = PageRequest.of(page, size);
if (userId <= 0L) {
return repository.findAll(pageRequest);
}
else {
userService.get(userId);
return repository.findByUserId(userId, pageRequest);
}
}
// Получить элемент по идентификатору // Получить элемент по идентификатору
@Transactional(readOnly = true) @Transactional(readOnly = true)
public MessageEntity get(Long userId, Long id) { public MessageEntity get(Long userId, Long id) {

View File

@ -13,6 +13,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.example.demo.core.api.PageDto;
import com.example.demo.core.api.PageDtoMapper;
import com.example.demo.core.configuration.Constants; import com.example.demo.core.configuration.Constants;
import com.example.demo.orders.model.OrderEntity; import com.example.demo.orders.model.OrderEntity;
import com.example.demo.orders.model.OrderGrouped; import com.example.demo.orders.model.OrderGrouped;
@ -60,12 +62,12 @@ public class OrderController {
// Получить все элементы или по заданному фильтру // Получить все элементы или по заданному фильтру
@GetMapping @GetMapping
public List<OrderDto> getAll( public PageDto<OrderDto> getAll(
@PathVariable(name = "user") Long userId, @PathVariable(name = "user") Long userId,
@RequestParam(name = "typeId", defaultValue = "0") Long typeId) { @RequestParam(name = "typeId", defaultValue = "0") Long typeId,
return orderService.getAll(userId, typeId).stream() @RequestParam(name = "page", defaultValue = "0") int page,
.map(this::toDto) @RequestParam(name = "size", defaultValue = Constants.DEFAULT_PAGE_SIZE) int size) {
.toList(); return PageDtoMapper.toDto(orderService.getAll(userId, typeId, page, size), this::toDto);
} }
// Получить элемент по идентификатору // Получить элемент по идентификатору

View File

@ -4,22 +4,31 @@ import java.util.Optional;
import java.util.List; import java.util.List;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import com.example.demo.orders.model.OrderEntity; import com.example.demo.orders.model.OrderEntity;
import com.example.demo.orders.model.OrderGrouped; import com.example.demo.orders.model.OrderGrouped;
// Хранилище для сущности "Заказ" (Заказ, содержащий книги) // Хранилище для сущности "Заказ" (Заказ, содержащий книги)
public interface OrderRepository extends CrudRepository<OrderEntity, Long> { public interface OrderRepository extends CrudRepository<OrderEntity, Long>, PagingAndSortingRepository<OrderEntity, Long> {
// Получить заказ по пользователю и идентификатору // Получить заказ по пользователю и идентификатору
Optional<OrderEntity> findOneByUserIdAndId(Long userId, Long id); Optional<OrderEntity> findOneByUserIdAndId(Long userId, Long id);
// Получить список заказов по пользователю // Получить список заказов по пользователю
List<OrderEntity> findByUserId(Long userId); List<OrderEntity> findByUserId(Long userId);
// Получить список заказов по пользователю (с пагинацией)
Page<OrderEntity> findByUserId(Long userId, Pageable pageable);
// Получить список заказов по типу // Получить список заказов по типу
List<OrderEntity> findByUserIdAndTypeId(Long userId, Long typeId); List<OrderEntity> findByUserIdAndTypeId(Long userId, Long typeId);
// Получить список заказов по типу (с пагинацией)
Page<OrderEntity> findByUserIdAndTypeId(Long userId, Long typeId, Pageable pageable);
// Получить заказы, сгруппированные по типу // Получить заказы, сгруппированные по типу
// select // select
// type.name, // type.name,

View File

@ -2,6 +2,8 @@ package com.example.demo.orders.service;
import java.util.List; import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -39,6 +41,17 @@ public class OrderService {
} }
} }
// Получить все элементы или по заданному фильтру (с пагинацией)
@Transactional(readOnly = true)
public Page<OrderEntity> getAll(long userId, long typeId, int page, int size) {
final PageRequest pageRequest = PageRequest.of(page, size);
userService.get(userId);
if (typeId <= 0L) {
return repository.findByUserId(userId, pageRequest);
}
return repository.findByUserIdAndTypeId(userId, typeId, pageRequest);
}
// Получить элемент по идентификатору // Получить элемент по идентификатору
@Transactional(readOnly = true) @Transactional(readOnly = true)
public OrderEntity get(Long userId, Long id) { public OrderEntity get(Long userId, Long id) {