diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/PagingAndSortingQueryParams.java b/src/main/java/xyz/zhouxy/plusone/commons/util/PagingAndSortingQueryParams.java
index 0a12e18..ab712f6 100644
--- a/src/main/java/xyz/zhouxy/plusone/commons/util/PagingAndSortingQueryParams.java
+++ b/src/main/java/xyz/zhouxy/plusone/commons/util/PagingAndSortingQueryParams.java
@@ -19,14 +19,16 @@ package xyz.zhouxy.plusone.commons.util;
import java.util.Collections;
import java.util.LinkedList;
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 org.apache.commons.lang3.StringUtils;
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;
@@ -38,35 +40,36 @@ import xyz.zhouxy.plusone.commons.annotation.Virtual;
* 提供 {@code getOffset} 方法计算 SQL 语句中 {@code offset} 的值。
*
*
- * @author ZhouXY
+ * @author ZhouXY
* @see PageDTO
*/
public class PagingAndSortingQueryParams {
- // TODO 【优化】 优化该工具,使之支持分别按照多个不同列的递增或递减排序。
+ // TODO 【优化】 进一步优化 API
private static final int DEFAULT_PAGE_SIZE = 15;
private int size;
private long pageNum;
- private final List orderBy = new LinkedList<>();
+ private final List orderBy = new LinkedList<>();
- private final Set sortableProperties;
+ private static final Pattern orderByStrPattern = Pattern.compile("^[a-zA-Z]\\w+-(desc|asc|DESC|ASC)$");
- public PagingAndSortingQueryParams() {
- this.sortableProperties = Collections.emptySet();
- }
+ private final Map sortableProperties;
- public PagingAndSortingQueryParams(String... sortableProperties) {
- for (String p : sortableProperties) {
- Preconditions.checkArgument(StringUtils.isNotBlank(p), "Property name must not be blank.");
+ public PagingAndSortingQueryParams(Map sortableProperties) {
+ Preconditions.checkArgument(sortableProperties != null && !sortableProperties.isEmpty(),
+ "Sortable properties can not be empty.");
+ for (Entry p : sortableProperties.entrySet()) {
+ Preconditions.checkArgument(StringUtils.isNotBlank(p.getKey()) && StringUtils.isNotBlank(p.getValue()),
+ "Property name must not be blank.");
}
- this.sortableProperties = ImmutableSet.builder().add(sortableProperties).build();
+ this.sortableProperties = ImmutableMap.copyOf(sortableProperties);
}
// Getters
- public final List getOrderBy() {
+ public final List getOrderBy() {
return Collections.unmodifiableList(this.orderBy);
}
@@ -86,14 +89,12 @@ public class PagingAndSortingQueryParams {
// Setters
- public final void setOrderBy(@Nullable List properties) {
+ public final void setOrderBy(@Nullable List orderByStrList) {
this.orderBy.clear();
- if (properties != null && !properties.isEmpty()) {
- for (String colName : properties) {
- Preconditions.checkArgument(this.sortableProperties.contains(colName),
- "The property name must be in the set of sortable properties.");
- }
- this.orderBy.addAll(properties);
+ if (orderByStrList != null) {
+ orderByStrList.stream()
+ .map(this::generateSortableProperty)
+ .forEach(this.orderBy::add);
}
}
@@ -114,7 +115,49 @@ public class PagingAndSortingQueryParams {
@Override
public String toString() {
- return "PagingAndSortingQueryParams [size=" + size + ", pageNum=" + pageNum + ", orderBy=" + orderBy
+ return "PagingAndSortingQueryParams ["
+ + "size=" + size
+ + ", pageNum=" + pageNum
+ + ", offset=" + getOffset()
+ + ", orderBy=" + orderBy
+ ", 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;
+ }
+ }
}