diff --git a/demo/data.mv.db b/demo/data.mv.db index 9876839..e30b119 100644 Binary files a/demo/data.mv.db and b/demo/data.mv.db differ diff --git a/demo/src/main/java/com/example/demo/core/api/PageDto.java b/demo/src/main/java/com/example/demo/core/api/PageDto.java new file mode 100644 index 0000000..627ec15 --- /dev/null +++ b/demo/src/main/java/com/example/demo/core/api/PageDto.java @@ -0,0 +1,117 @@ +package com.example.demo.core.api; + +import java.util.ArrayList; +import java.util.List; + +// DTO для страниц (Пагинация) +public class PageDto { + // Список элементов + private List 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 getItems() { + return items; + } + + public void setItems(List 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; + } +} diff --git a/demo/src/main/java/com/example/demo/core/api/PageDtoMapper.java b/demo/src/main/java/com/example/demo/core/api/PageDtoMapper.java new file mode 100644 index 0000000..390ba14 --- /dev/null +++ b/demo/src/main/java/com/example/demo/core/api/PageDtoMapper.java @@ -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 PageDto toDto(Page page, Function mapper) { + final PageDto 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; + } +} diff --git a/demo/src/main/java/com/example/demo/core/configuration/Constants.java b/demo/src/main/java/com/example/demo/core/configuration/Constants.java index 8e0fc28..611ec8e 100644 --- a/demo/src/main/java/com/example/demo/core/configuration/Constants.java +++ b/demo/src/main/java/com/example/demo/core/configuration/Constants.java @@ -8,6 +8,9 @@ public class Constants { // Базовый префикс REST-API public static final String API_URL = "/api/1.0"; + // Размер страницы пагинации + public static final String DEFAULT_PAGE_SIZE = "5"; + private Constants() { } } diff --git a/demo/src/main/java/com/example/demo/messages/api/MessageController.java b/demo/src/main/java/com/example/demo/messages/api/MessageController.java index 66f12ed..750b385 100644 --- a/demo/src/main/java/com/example/demo/messages/api/MessageController.java +++ b/demo/src/main/java/com/example/demo/messages/api/MessageController.java @@ -10,8 +10,11 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; 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.messages.model.MessageEntity; import com.example.demo.messages.service.MessageService; @@ -47,10 +50,11 @@ public class MessageController { // Получить все элементы @GetMapping - public List getAll(@PathVariable(name = "user") Long userId) { - return messageService.getAll(userId).stream() - .map(this::toDto) - .toList(); + public PageDto getAll( + @PathVariable(name = "user") Long userId, + @RequestParam(name = "page", defaultValue = "0") int page, + @RequestParam(name = "size", defaultValue = Constants.DEFAULT_PAGE_SIZE) int size) { + return PageDtoMapper.toDto(messageService.getAll(userId, page, size), this::toDto); } // Получить элемент по идентификатору diff --git a/demo/src/main/java/com/example/demo/messages/repository/MessageRepository.java b/demo/src/main/java/com/example/demo/messages/repository/MessageRepository.java index 50c5325..18b4d7c 100644 --- a/demo/src/main/java/com/example/demo/messages/repository/MessageRepository.java +++ b/demo/src/main/java/com/example/demo/messages/repository/MessageRepository.java @@ -3,6 +3,8 @@ package com.example.demo.messages.repository; import java.util.List; import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.repository.CrudRepository; import com.example.demo.messages.model.MessageEntity; @@ -12,6 +14,12 @@ public interface MessageRepository extends CrudRepository { // Получить сообщение по пользователю и идентификатору Optional findOnyByUserIdAndId(Long userId, Long id); + // Получить список всех сообщений (с пагинацией) + Page findAll(Pageable pageable); + // Получить список сообщений по пользователю List findByUserId(Long userId); + + // Получить список сообщений по пользователю (с пагинацией) + Page findByUserId(Long userId, Pageable pageable); } diff --git a/demo/src/main/java/com/example/demo/messages/service/MessageService.java b/demo/src/main/java/com/example/demo/messages/service/MessageService.java index 769946d..1324713 100644 --- a/demo/src/main/java/com/example/demo/messages/service/MessageService.java +++ b/demo/src/main/java/com/example/demo/messages/service/MessageService.java @@ -3,6 +3,8 @@ package com.example.demo.messages.service; import java.util.List; 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.transaction.annotation.Transactional; @@ -39,6 +41,19 @@ public class MessageService { } } + // Получить все элементы или по заданному фильтру (с пагинацией) + @Transactional(readOnly = true) + public Page 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) public MessageEntity get(Long userId, Long id) { diff --git a/demo/src/main/java/com/example/demo/orders/api/OrderController.java b/demo/src/main/java/com/example/demo/orders/api/OrderController.java index ba2ca92..73f5953 100644 --- a/demo/src/main/java/com/example/demo/orders/api/OrderController.java +++ b/demo/src/main/java/com/example/demo/orders/api/OrderController.java @@ -13,6 +13,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; 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.orders.model.OrderEntity; import com.example.demo.orders.model.OrderGrouped; @@ -60,12 +62,12 @@ public class OrderController { // Получить все элементы или по заданному фильтру @GetMapping - public List getAll( + public PageDto getAll( @PathVariable(name = "user") Long userId, - @RequestParam(name = "typeId", defaultValue = "0") Long typeId) { - return orderService.getAll(userId, typeId).stream() - .map(this::toDto) - .toList(); + @RequestParam(name = "typeId", defaultValue = "0") Long typeId, + @RequestParam(name = "page", defaultValue = "0") int page, + @RequestParam(name = "size", defaultValue = Constants.DEFAULT_PAGE_SIZE) int size) { + return PageDtoMapper.toDto(orderService.getAll(userId, typeId, page, size), this::toDto); } // Получить элемент по идентификатору diff --git a/demo/src/main/java/com/example/demo/orders/repository/OrderRepository.java b/demo/src/main/java/com/example/demo/orders/repository/OrderRepository.java index 84a8189..a54ba45 100644 --- a/demo/src/main/java/com/example/demo/orders/repository/OrderRepository.java +++ b/demo/src/main/java/com/example/demo/orders/repository/OrderRepository.java @@ -4,22 +4,31 @@ import java.util.Optional; import java.util.List; 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 com.example.demo.orders.model.OrderEntity; import com.example.demo.orders.model.OrderGrouped; // Хранилище для сущности "Заказ" (Заказ, содержащий книги) -public interface OrderRepository extends CrudRepository { +public interface OrderRepository extends CrudRepository, PagingAndSortingRepository { // Получить заказ по пользователю и идентификатору Optional findOneByUserIdAndId(Long userId, Long id); // Получить список заказов по пользователю List findByUserId(Long userId); + // Получить список заказов по пользователю (с пагинацией) + Page findByUserId(Long userId, Pageable pageable); + // Получить список заказов по типу List findByUserIdAndTypeId(Long userId, Long typeId); + // Получить список заказов по типу (с пагинацией) + Page findByUserIdAndTypeId(Long userId, Long typeId, Pageable pageable); + // Получить заказы, сгруппированные по типу // select // type.name, diff --git a/demo/src/main/java/com/example/demo/orders/service/OrderService.java b/demo/src/main/java/com/example/demo/orders/service/OrderService.java index b00b172..dd294f4 100644 --- a/demo/src/main/java/com/example/demo/orders/service/OrderService.java +++ b/demo/src/main/java/com/example/demo/orders/service/OrderService.java @@ -2,6 +2,8 @@ package com.example.demo.orders.service; import java.util.List; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -39,6 +41,17 @@ public class OrderService { } } + // Получить все элементы или по заданному фильтру (с пагинацией) + @Transactional(readOnly = true) + public Page 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) public OrderEntity get(Long userId, Long id) {