diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/PagingAndSortingQueryParams.java b/src/main/java/xyz/zhouxy/plusone/commons/model/dto/PagingAndSortingQueryParams.java similarity index 68% rename from src/main/java/xyz/zhouxy/plusone/commons/util/PagingAndSortingQueryParams.java rename to src/main/java/xyz/zhouxy/plusone/commons/model/dto/PagingAndSortingQueryParams.java index 4f4f5bb..9db260a 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/PagingAndSortingQueryParams.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/model/dto/PagingAndSortingQueryParams.java @@ -14,13 +14,12 @@ * limitations under the License. */ -package xyz.zhouxy.plusone.commons.util; +package xyz.zhouxy.plusone.commons.model.dto; -import java.util.Collections; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.regex.Pattern; +import java.util.stream.Collectors; import javax.annotation.Nullable; @@ -40,72 +39,53 @@ import xyz.zhouxy.plusone.commons.annotation.Virtual; *

* * @author ZhouXY - * @see PageDTO + * @see PageResult */ public class PagingAndSortingQueryParams { - // TODO 【优化】 进一步优化 API - private static final int DEFAULT_PAGE_SIZE = 15; - private int size; - private long pageNum; - private final List orderBy = new LinkedList<>(); + private Integer size; + private Long pageNum; + private List orderBy; - private static final Pattern orderByStrPattern = Pattern.compile("^[a-zA-Z]\\w+-(desc|asc|DESC|ASC)$"); + private static final Pattern sortStrPattern = Pattern.compile("^[a-zA-Z]\\w+-(desc|asc|DESC|ASC)$"); private final Map sortableProperties; public PagingAndSortingQueryParams(Map sortableProperties) { Preconditions.checkArgument(sortableProperties != null && !sortableProperties.isEmpty(), "Sortable properties can not be empty."); - sortableProperties.forEach((k, v) -> + sortableProperties.forEach((k, v) -> Preconditions.checkArgument(StringUtils.isNotBlank(k) && StringUtils.isNotBlank(v), "Property name must not be blank.")); this.sortableProperties = ImmutableMap.copyOf(sortableProperties); } - // Getters - - public final List getOrderBy() { - return Collections.unmodifiableList(this.orderBy); - } - - public final int getSize() { - return this.size; - } - - public final long getPageNum() { - return this.pageNum; - } - - public final long getOffset() { - return (this.pageNum - 1) * this.size; - } - - // Getters end - // Setters - public final void setOrderBy(@Nullable List orderByStrList) { - this.orderBy.clear(); - if (orderByStrList != null) { - orderByStrList.stream() - .map(this::generateSortableProperty) - .forEach(this.orderBy::add); - } + public final void setOrderBy(@Nullable List orderBy) { + this.orderBy = orderBy; } public final void setSize(@Nullable Integer size) { - this.size = size != null ? size : defaultSizeInternal(); + this.size = size; } public final void setPageNum(@Nullable Long pageNum) { - this.pageNum = pageNum != null ? pageNum : 1L; + this.pageNum = pageNum; } // Setters end + public final PagingParams buildPagingParams() { + final int sizeValue = this.size != null ? this.size : defaultSizeInternal(); + final long pageNumValue = this.pageNum != null ? this.pageNum : 1L; + final List propertiesToSort = this.orderBy.stream().map(this::generateSortableProperty) + .collect(Collectors.toList()); + return new PagingParams(sizeValue, pageNumValue, propertiesToSort); + } + @Virtual protected int defaultSizeInternal() { return DEFAULT_PAGE_SIZE; @@ -116,13 +96,13 @@ public class PagingAndSortingQueryParams { return "PagingAndSortingQueryParams [" + "size=" + size + ", pageNum=" + pageNum - + ", offset=" + getOffset() + ", orderBy=" + orderBy - + ", sortableProperties=" + sortableProperties + "]"; + + ", sortableProperties=" + sortableProperties + + "]"; } private SortableProperty generateSortableProperty(String orderByStr) { - Preconditions.checkArgument(orderByStrPattern.matcher(orderByStr).matches()); + Preconditions.checkArgument(PagingAndSortingQueryParams.sortStrPattern.matcher(orderByStr).matches()); String[] propertyNameAndOrderType = orderByStr.split("-"); Preconditions.checkArgument(propertyNameAndOrderType.length == 2); @@ -139,11 +119,15 @@ public class PagingAndSortingQueryParams { private final String columnName; private final String orderType; - private SortableProperty(String propertyName, String columnName, String orderType) { + private final String sqlSnippet; + + SortableProperty(String propertyName, String columnName, String orderType) { this.propertyName = propertyName; this.columnName = columnName; Preconditions.checkArgument("ASC".equalsIgnoreCase(orderType) || "DESC".equalsIgnoreCase(orderType)); this.orderType = orderType.toUpperCase(); + + this.sqlSnippet = this.propertyName + " " + this.orderType; } public String getPropertyName() { @@ -157,5 +141,19 @@ public class PagingAndSortingQueryParams { public String getOrderType() { return orderType; } + + public String getSqlSnippet() { + return sqlSnippet; + } + + @Override + public String toString() { + return "SortableProperty [" + + "propertyName=" + propertyName + + ", columnName=" + columnName + + ", orderType=" + orderType + + "]"; + } } + } diff --git a/src/main/java/xyz/zhouxy/plusone/commons/model/dto/PagingParams.java b/src/main/java/xyz/zhouxy/plusone/commons/model/dto/PagingParams.java new file mode 100644 index 0000000..5d03622 --- /dev/null +++ b/src/main/java/xyz/zhouxy/plusone/commons/model/dto/PagingParams.java @@ -0,0 +1,47 @@ +package xyz.zhouxy.plusone.commons.model.dto; + +import java.util.Collections; +import java.util.List; + +import xyz.zhouxy.plusone.commons.model.dto.PagingAndSortingQueryParams.SortableProperty; + +public class PagingParams { + + private final int size; + private final long pageNum; + private final long offset; + private final List orderBy; + + PagingParams(int size, long pageNum, List orderBy) { + this.size = size; + this.pageNum = pageNum; + this.offset = (pageNum - 1) * size; + this.orderBy = orderBy; + } + + // Getters + + public final List getOrderBy() { + return Collections.unmodifiableList(this.orderBy); + } + + public final int getSize() { + return this.size; + } + + public final long getPageNum() { + return this.pageNum; + } + + public final long getOffset() { + return this.offset; + } + + // Getters end + + @Override + public String toString() { + return "PageInfo [size=" + size + ", pageNum=" + pageNum + ", orderBy=" + orderBy + ", offset=" + + getOffset() + "]"; + } +} diff --git a/src/test/java/xyz/zhouxy/plusone/commons/queryparams/test/PagingAndSortingQueryParamsTests.java b/src/test/java/xyz/zhouxy/plusone/commons/queryparams/test/PagingAndSortingQueryParamsTests.java new file mode 100644 index 0000000..156a57c --- /dev/null +++ b/src/test/java/xyz/zhouxy/plusone/commons/queryparams/test/PagingAndSortingQueryParamsTests.java @@ -0,0 +1,143 @@ +package xyz.zhouxy.plusone.commons.queryparams.test; + +import java.io.IOException; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.google.common.collect.ImmutableMap; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; +import xyz.zhouxy.plusone.commons.model.dto.PagingAndSortingQueryParams; +import xyz.zhouxy.plusone.commons.model.dto.PagingParams; + +@Slf4j +public // +class PagingAndSortingQueryParamsTests { + static final String JSON_STR = "" + + "{\n" + + " \"size\": 15,\n" + + " \"orderBy\": [\"username-asc\"],\n" + + " \"createTimeStart\": \"2024-05-06\",\n" + + " \"createTimeEnd\": \"2024-07-06\",\n" + + " \"updateTimeStart\": \"2024-08-06\",\n" + + " \"updateTimeEnd\": \"2024-10-06\",\n" + + " \"mobilePhone\": \"13169053215\"\n" + + "}"; + + @Test + void testJackson() throws Exception { + try { + ObjectMapper om = new ObjectMapper(); + om.registerModule(new JavaTimeModule()); + AccountQueryParams params = om.readValue(JSON_STR, AccountQueryParams.class); + log.info(params.toString()); + PagingParams pagingParams = params.buildPagingParams(); + log.info("pagingParams: {}", pagingParams); + } catch (Exception e) { + log.error("测试不通过", e); + throw e; + } + } + + static final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + static final TypeAdapter dateAdapter = new TypeAdapter() { + + @Override + public void write(JsonWriter out, LocalDate value) throws IOException { + out.value(dateFormatter.format(value)); + } + + @Override + public LocalDate read(JsonReader in) throws IOException { + return LocalDate.parse(in.nextString(), dateFormatter); + } + + }; + + @Test + void testGson() throws Exception { + try { + Gson gson = new GsonBuilder() + .registerTypeAdapter(LocalDate.class, dateAdapter) + .create(); + AccountQueryParams params = gson.fromJson(JSON_STR, AccountQueryParams.class); + log.info(params.toString()); + PagingParams pagingParams = params.buildPagingParams(); + log.info("pagingParams: {}", pagingParams); + } catch (Exception e) { + log.error("测试不通过", e); + throw e; + } + } +} + + +/** + * 账号信息查询参数 + * + * @author ZhouXY + */ +@ToString(callSuper = true) +class AccountQueryParams extends PagingAndSortingQueryParams { + + private static final Map PROPERTY_COLUMN_MAP = ImmutableMap.builder() + .put("id", "id") + .put("username", "username") + .put("email", "email") + .put("mobilePhone", "mobile_phone") + .put("status", "status") + .put("nickname", "nickname") + .put("sex", "sex") + .put("createdBy", "created_by") + .put("createTime", "create_time") + .put("updatedBy", "updated_by") + .put("updateTime", "update_time") + .build(); + + public AccountQueryParams() { + super(PROPERTY_COLUMN_MAP); + } + + private @Getter @Setter Long id; + private @Getter @Setter String username; + private @Getter @Setter String email; + private @Getter @Setter String mobilePhone; + private @Getter @Setter Integer status; + private @Getter @Setter String nickname; + private @Getter @Setter Integer sex; + private @Getter @Setter Long createdBy; + private @Getter @Setter LocalDate createTimeStart; + private @Setter LocalDate createTimeEnd; + private @Getter @Setter Long updatedBy; + private @Getter @Setter LocalDate updateTimeStart; + private @Setter LocalDate updateTimeEnd; + private @Getter @Setter Long roleId; + + public LocalDate getCreateTimeEnd() { + if (this.createTimeEnd == null) { + return null; + } + return this.createTimeEnd.plusDays(1); + } + + public LocalDate getUpdateTimeEnd() { + if (this.updateTimeEnd == null) { + return null; + } + return this.updateTimeEnd.plusDays(1); + } +}