forked from plusone/plusone-commons
修改 API,也使 PagingAndSortingQueryParams 支持 Gson。
parent
516c9d9d79
commit
71b3b193d1
|
@ -14,13 +14,12 @@
|
||||||
* limitations under the License.
|
* 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.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
@ -40,72 +39,53 @@ import xyz.zhouxy.plusone.commons.annotation.Virtual;
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author <a href="http://zhouxy.xyz:3000/ZhouXY108">ZhouXY</a>
|
* @author <a href="http://zhouxy.xyz:3000/ZhouXY108">ZhouXY</a>
|
||||||
* @see PageDTO
|
* @see PageResult
|
||||||
*/
|
*/
|
||||||
public class PagingAndSortingQueryParams {
|
public class PagingAndSortingQueryParams {
|
||||||
|
|
||||||
// TODO 【优化】 进一步优化 API
|
|
||||||
|
|
||||||
private static final int DEFAULT_PAGE_SIZE = 15;
|
private static final int DEFAULT_PAGE_SIZE = 15;
|
||||||
|
|
||||||
private int size;
|
private Integer size;
|
||||||
private long pageNum;
|
private Long pageNum;
|
||||||
private final List<SortableProperty> orderBy = new LinkedList<>();
|
private List<String> 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<String, String> sortableProperties;
|
private final Map<String, String> sortableProperties;
|
||||||
|
|
||||||
public PagingAndSortingQueryParams(Map<String, String> sortableProperties) {
|
public PagingAndSortingQueryParams(Map<String, String> sortableProperties) {
|
||||||
Preconditions.checkArgument(sortableProperties != null && !sortableProperties.isEmpty(),
|
Preconditions.checkArgument(sortableProperties != null && !sortableProperties.isEmpty(),
|
||||||
"Sortable properties can not be empty.");
|
"Sortable properties can not be empty.");
|
||||||
sortableProperties.forEach((k, v) ->
|
sortableProperties.forEach((k, v) ->
|
||||||
Preconditions.checkArgument(StringUtils.isNotBlank(k) && StringUtils.isNotBlank(v),
|
Preconditions.checkArgument(StringUtils.isNotBlank(k) && StringUtils.isNotBlank(v),
|
||||||
"Property name must not be blank."));
|
"Property name must not be blank."));
|
||||||
this.sortableProperties = ImmutableMap.copyOf(sortableProperties);
|
this.sortableProperties = ImmutableMap.copyOf(sortableProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getters
|
|
||||||
|
|
||||||
public final List<SortableProperty> 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
|
// Setters
|
||||||
|
|
||||||
public final void setOrderBy(@Nullable List<String> orderByStrList) {
|
public final void setOrderBy(@Nullable List<String> orderBy) {
|
||||||
this.orderBy.clear();
|
this.orderBy = orderBy;
|
||||||
if (orderByStrList != null) {
|
|
||||||
orderByStrList.stream()
|
|
||||||
.map(this::generateSortableProperty)
|
|
||||||
.forEach(this.orderBy::add);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void setSize(@Nullable Integer size) {
|
public final void setSize(@Nullable Integer size) {
|
||||||
this.size = size != null ? size : defaultSizeInternal();
|
this.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void setPageNum(@Nullable Long pageNum) {
|
public final void setPageNum(@Nullable Long pageNum) {
|
||||||
this.pageNum = pageNum != null ? pageNum : 1L;
|
this.pageNum = pageNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setters end
|
// 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<SortableProperty> propertiesToSort = this.orderBy.stream().map(this::generateSortableProperty)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
return new PagingParams(sizeValue, pageNumValue, propertiesToSort);
|
||||||
|
}
|
||||||
|
|
||||||
@Virtual
|
@Virtual
|
||||||
protected int defaultSizeInternal() {
|
protected int defaultSizeInternal() {
|
||||||
return DEFAULT_PAGE_SIZE;
|
return DEFAULT_PAGE_SIZE;
|
||||||
|
@ -116,13 +96,13 @@ public class PagingAndSortingQueryParams {
|
||||||
return "PagingAndSortingQueryParams ["
|
return "PagingAndSortingQueryParams ["
|
||||||
+ "size=" + size
|
+ "size=" + size
|
||||||
+ ", pageNum=" + pageNum
|
+ ", pageNum=" + pageNum
|
||||||
+ ", offset=" + getOffset()
|
|
||||||
+ ", orderBy=" + orderBy
|
+ ", orderBy=" + orderBy
|
||||||
+ ", sortableProperties=" + sortableProperties + "]";
|
+ ", sortableProperties=" + sortableProperties
|
||||||
|
+ "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
private SortableProperty generateSortableProperty(String orderByStr) {
|
private SortableProperty generateSortableProperty(String orderByStr) {
|
||||||
Preconditions.checkArgument(orderByStrPattern.matcher(orderByStr).matches());
|
Preconditions.checkArgument(PagingAndSortingQueryParams.sortStrPattern.matcher(orderByStr).matches());
|
||||||
String[] propertyNameAndOrderType = orderByStr.split("-");
|
String[] propertyNameAndOrderType = orderByStr.split("-");
|
||||||
Preconditions.checkArgument(propertyNameAndOrderType.length == 2);
|
Preconditions.checkArgument(propertyNameAndOrderType.length == 2);
|
||||||
|
|
||||||
|
@ -139,11 +119,15 @@ public class PagingAndSortingQueryParams {
|
||||||
private final String columnName;
|
private final String columnName;
|
||||||
private final String orderType;
|
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.propertyName = propertyName;
|
||||||
this.columnName = columnName;
|
this.columnName = columnName;
|
||||||
Preconditions.checkArgument("ASC".equalsIgnoreCase(orderType) || "DESC".equalsIgnoreCase(orderType));
|
Preconditions.checkArgument("ASC".equalsIgnoreCase(orderType) || "DESC".equalsIgnoreCase(orderType));
|
||||||
this.orderType = orderType.toUpperCase();
|
this.orderType = orderType.toUpperCase();
|
||||||
|
|
||||||
|
this.sqlSnippet = this.propertyName + " " + this.orderType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPropertyName() {
|
public String getPropertyName() {
|
||||||
|
@ -157,5 +141,19 @@ public class PagingAndSortingQueryParams {
|
||||||
public String getOrderType() {
|
public String getOrderType() {
|
||||||
return orderType;
|
return orderType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSqlSnippet() {
|
||||||
|
return sqlSnippet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "SortableProperty ["
|
||||||
|
+ "propertyName=" + propertyName
|
||||||
|
+ ", columnName=" + columnName
|
||||||
|
+ ", orderType=" + orderType
|
||||||
|
+ "]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -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<SortableProperty> orderBy;
|
||||||
|
|
||||||
|
PagingParams(int size, long pageNum, List<SortableProperty> orderBy) {
|
||||||
|
this.size = size;
|
||||||
|
this.pageNum = pageNum;
|
||||||
|
this.offset = (pageNum - 1) * size;
|
||||||
|
this.orderBy = orderBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
|
||||||
|
public final List<SortableProperty> 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() + "]";
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<LocalDate> dateAdapter = new TypeAdapter<LocalDate>() {
|
||||||
|
|
||||||
|
@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 <a href="http://zhouxy.xyz:3000/ZhouXY108">ZhouXY</a>
|
||||||
|
*/
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
class AccountQueryParams extends PagingAndSortingQueryParams {
|
||||||
|
|
||||||
|
private static final Map<String, String> PROPERTY_COLUMN_MAP = ImmutableMap.<String, String>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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue