支持分别按照多个不同列的递增或递减排序。

dev
ZhouXY108 2024-04-07 16:21:39 +08:00
parent b2ece2fab5
commit 9af12f35ca
1 changed files with 65 additions and 22 deletions

View File

@ -19,14 +19,16 @@ package xyz.zhouxy.plusone.commons.util;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableMap;
import xyz.zhouxy.plusone.commons.annotation.Virtual; import xyz.zhouxy.plusone.commons.annotation.Virtual;
@ -38,35 +40,36 @@ import xyz.zhouxy.plusone.commons.annotation.Virtual;
* {@code getOffset} SQL {@code offset} * {@code getOffset} SQL {@code offset}
* </p> * </p>
* *
* @author <a href="https://gitee.com/zhouxy108">ZhouXY</a> * @author <a href="http://zhouxy.xyz:3000/ZhouXY108">ZhouXY</a>
* @see PageDTO * @see PageDTO
*/ */
public class PagingAndSortingQueryParams { public class PagingAndSortingQueryParams {
// TODO 【优化】 优化该工具,使之支持分别按照多个不同列的递增或递减排序。 // TODO 【优化】 进一步优化 API
private static final int DEFAULT_PAGE_SIZE = 15; private static final int DEFAULT_PAGE_SIZE = 15;
private int size; private int size;
private long pageNum; private long pageNum;
private final List<String> orderBy = new LinkedList<>(); private final List<SortableProperty> orderBy = new LinkedList<>();
private final Set<String> sortableProperties; private static final Pattern orderByStrPattern = Pattern.compile("^[a-zA-Z]\\w+-(desc|asc|DESC|ASC)$");
public PagingAndSortingQueryParams() { private final Map<String, String> sortableProperties;
this.sortableProperties = Collections.emptySet();
public PagingAndSortingQueryParams(Map<String, String> sortableProperties) {
Preconditions.checkArgument(sortableProperties != null && !sortableProperties.isEmpty(),
"Sortable properties can not be empty.");
for (Entry<String, String> p : sortableProperties.entrySet()) {
Preconditions.checkArgument(StringUtils.isNotBlank(p.getKey()) && StringUtils.isNotBlank(p.getValue()),
"Property name must not be blank.");
} }
this.sortableProperties = ImmutableMap.copyOf(sortableProperties);
public PagingAndSortingQueryParams(String... sortableProperties) {
for (String p : sortableProperties) {
Preconditions.checkArgument(StringUtils.isNotBlank(p), "Property name must not be blank.");
}
this.sortableProperties = ImmutableSet.<String>builder().add(sortableProperties).build();
} }
// Getters // Getters
public final List<String> getOrderBy() { public final List<SortableProperty> getOrderBy() {
return Collections.unmodifiableList(this.orderBy); return Collections.unmodifiableList(this.orderBy);
} }
@ -86,14 +89,12 @@ public class PagingAndSortingQueryParams {
// Setters // Setters
public final void setOrderBy(@Nullable List<String> properties) { public final void setOrderBy(@Nullable List<String> orderByStrList) {
this.orderBy.clear(); this.orderBy.clear();
if (properties != null && !properties.isEmpty()) { if (orderByStrList != null) {
for (String colName : properties) { orderByStrList.stream()
Preconditions.checkArgument(this.sortableProperties.contains(colName), .map(this::generateSortableProperty)
"The property name must be in the set of sortable properties."); .forEach(this.orderBy::add);
}
this.orderBy.addAll(properties);
} }
} }
@ -114,7 +115,49 @@ public class PagingAndSortingQueryParams {
@Override @Override
public String toString() { public String toString() {
return "PagingAndSortingQueryParams [size=" + size + ", pageNum=" + pageNum + ", orderBy=" + orderBy 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());
String[] propertyNameAndOrderType = orderByStr.split("-");
Preconditions.checkArgument(propertyNameAndOrderType.length == 2);
String propertyName = propertyNameAndOrderType[0];
Preconditions.checkArgument(sortableProperties.containsKey(propertyName),
"The property name must be in the set of sortable properties.");
String columnName = sortableProperties.get(propertyName);
String orderType = propertyNameAndOrderType[1];
return new SortableProperty(propertyName, columnName, orderType);
}
public static final class SortableProperty {
private final String propertyName;
private final String columnName;
private final String orderType;
private 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();
}
public String getPropertyName() {
return propertyName;
}
public String getColumnName() {
return columnName;
}
public String getOrderType() {
return orderType;
}
}
} }