refactor!: 优化 PagingAndSortingQueryParams (!7 @Gitee)
`PagingAndSortingQueryParams` 的构造器中必须传入一个 `PagingParamsBuilder`, 构建分页参数时使用此 `PagingParamsBuilder`。 只要子类确保同一场景下共用一个 `PagingParamsBuilder` 实例,就不会导致白名单重复校验。
This commit is contained in:
@@ -35,8 +35,64 @@ import xyz.zhouxy.plusone.commons.util.StringTools;
|
|||||||
* 分页排序查询参数
|
* 分页排序查询参数
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* 根据传入的 {@code size} 和 {@code pageNum},
|
* 包含三个主要的属性:
|
||||||
* 提供 {@code getOffset} 方法计算 SQL 语句中 {@code offset} 的值。
|
* <ul>
|
||||||
|
* <li>size - 每页显示的记录数</li>
|
||||||
|
* <li>pageNum - 当前页码</li>
|
||||||
|
* <li>orderBy - 排序条件</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 分页必须伴随着排序,不然可能出现同一个对象重复出现在不同页,有的对象不被查询到的情况。
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 其中 {@code orderBy} 是一个 {@code List<String>},可以指定多个排序条件。
|
||||||
|
* 每个排序条件是一个字符串, 格式为“属性名-ASC”或“属性名-DESC”,分别表示升序和降序。
|
||||||
|
* 例如,当 {@code orderBy} 的值为 {@code ["name-ASC","age-DESC"]},
|
||||||
|
* 意味着要按 {@code name} 进行升序排列,{@code name} 相同的情况下则按 {@code age} 进行降序排列。
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 用户可继承 {@link PagingAndSortingQueryParams} 构建自己的分页查询入参,
|
||||||
|
* 子类需在构造器中调用 {@link PagingAndSortingQueryParams} 的构造器,
|
||||||
|
* 传入一个 {@link PagingParamsBuilder} 用于构建分页参数。
|
||||||
|
* 同一场景下,复用一个 {@link PagingParamsBuilder} 实例即可。
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 构建 {@link PagingParamsBuilder} 时,需传入一个 {@code Map} 作为可排序字段的白名单,
|
||||||
|
* {@code key} 是供前端指定用于排序的属性名,{@code value} 是对应数据库中的字段名。
|
||||||
|
* 只有在此白名单中的属性名才允许用于排序。
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* class AccountQueryParams extends PagingAndSortingQueryParams {
|
||||||
|
* private static final Map<String, String> PROPERTY_COLUMN_MAP = ImmutableMap.<String, String>builder()
|
||||||
|
* .put("id", "id")
|
||||||
|
* .put("username", "username")
|
||||||
|
* .build();
|
||||||
|
* private static final PagingParamsBuilder PAGING_PARAMS_BUILDER = PagingAndSortingQueryParams
|
||||||
|
* .pagingParamsBuilder(20, 100, PROPERTY_COLUMN_MAP);
|
||||||
|
*
|
||||||
|
* public AccountQueryParams() {
|
||||||
|
* // 所有的 AccountQueryParams 复用同一个 PagingParamsBuilder 实例
|
||||||
|
* super(PAGING_PARAMS_BUILDER);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* private @Getter @Setter Long id;
|
||||||
|
* private @Getter @Setter String username;
|
||||||
|
* private @Getter @Setter String email;
|
||||||
|
* private @Getter @Setter Integer status;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* public PageResult<AccountVO> queryPage(AccountQueryParams params) {
|
||||||
|
* // 获取分页参数
|
||||||
|
* PagingParams pagingParams = params.buildPagingParams();
|
||||||
|
* // 从 params 获取字段查询条件,从 pagingParams 获取分页条件,查询一页数据
|
||||||
|
* List<AccountVO> list = accountQueries.queryAccountList(params, pagingParams);
|
||||||
|
* // 查询总记录数
|
||||||
|
* long count = accountQueries.countAccount(params);
|
||||||
|
* // 返回分页结果
|
||||||
|
* return PageResult.of(list, count);
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author ZhouXY108 <luquanlion@outlook.com>
|
* @author ZhouXY108 <luquanlion@outlook.com>
|
||||||
* @see PagingParams
|
* @see PagingParams
|
||||||
@@ -44,10 +100,23 @@ import xyz.zhouxy.plusone.commons.util.StringTools;
|
|||||||
*/
|
*/
|
||||||
public class PagingAndSortingQueryParams {
|
public class PagingAndSortingQueryParams {
|
||||||
|
|
||||||
|
private final PagingParamsBuilder pagingParamsBuilder;
|
||||||
|
|
||||||
private Integer size;
|
private Integer size;
|
||||||
private Long pageNum;
|
private Long pageNum;
|
||||||
private List<String> orderBy;
|
private List<String> orderBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建一个 {@code PagingAndSortingQueryParams} 实例
|
||||||
|
*
|
||||||
|
* @param pagingParamsBuilder
|
||||||
|
* 分页参数构造器。
|
||||||
|
* 通过 {@link #pagingParamsBuilder(int, int, Map)} 创建,同一场景下只需要共享同一个实例。
|
||||||
|
*/
|
||||||
|
public PagingAndSortingQueryParams(PagingParamsBuilder pagingParamsBuilder) {
|
||||||
|
this.pagingParamsBuilder = pagingParamsBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
// Setters
|
// Setters
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -88,11 +157,31 @@ public class PagingAndSortingQueryParams {
|
|||||||
+ "]";
|
+ "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static PagingParamsBuilder pagingParamsBuilder(
|
/**
|
||||||
|
* 创建一个分页参数构造器
|
||||||
|
*
|
||||||
|
* @param defaultSize 默认每页大小
|
||||||
|
* @param maxSize 最大每页大小
|
||||||
|
* @param sortableProperties
|
||||||
|
* 可排序属性。
|
||||||
|
* key 是供前端指定用于排序的属性名,value 是对应数据库中的字段名。
|
||||||
|
* 只有在此白名单中的属性名才允许用于排序。
|
||||||
|
* @return 分页参数构造器
|
||||||
|
*/
|
||||||
|
public static PagingParamsBuilder pagingParamsBuilder(
|
||||||
int defaultSize, int maxSize, Map<String, String> sortableProperties) {
|
int defaultSize, int maxSize, Map<String, String> sortableProperties) {
|
||||||
return new PagingParamsBuilder(defaultSize, maxSize, sortableProperties);
|
return new PagingParamsBuilder(defaultSize, maxSize, sortableProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据当前查询参数,构建分页参数
|
||||||
|
*
|
||||||
|
* @return 分页参数
|
||||||
|
*/
|
||||||
|
public PagingParams buildPagingParams() {
|
||||||
|
return this.pagingParamsBuilder.buildPagingParams(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 可排序属性
|
* 可排序属性
|
||||||
*/
|
*/
|
||||||
@@ -103,7 +192,7 @@ public class PagingAndSortingQueryParams {
|
|||||||
|
|
||||||
private final String sqlSnippet;
|
private final String sqlSnippet;
|
||||||
|
|
||||||
SortableProperty(String propertyName, String columnName, String orderType) {
|
private SortableProperty(String propertyName, String columnName, String orderType) {
|
||||||
this.propertyName = propertyName;
|
this.propertyName = propertyName;
|
||||||
this.columnName = columnName;
|
this.columnName = columnName;
|
||||||
checkArgument("ASC".equalsIgnoreCase(orderType) || "DESC".equalsIgnoreCase(orderType));
|
checkArgument("ASC".equalsIgnoreCase(orderType) || "DESC".equalsIgnoreCase(orderType));
|
||||||
|
|||||||
@@ -234,6 +234,10 @@ class AccountQueryParams extends PagingAndSortingQueryParams {
|
|||||||
private static final PagingParamsBuilder PAGING_PARAMS_BUILDER = PagingAndSortingQueryParams
|
private static final PagingParamsBuilder PAGING_PARAMS_BUILDER = PagingAndSortingQueryParams
|
||||||
.pagingParamsBuilder(20, 100, PROPERTY_COLUMN_MAP);
|
.pagingParamsBuilder(20, 100, PROPERTY_COLUMN_MAP);
|
||||||
|
|
||||||
|
public AccountQueryParams() {
|
||||||
|
super(PAGING_PARAMS_BUILDER);
|
||||||
|
}
|
||||||
|
|
||||||
private @Getter @Setter Long id;
|
private @Getter @Setter Long id;
|
||||||
private @Getter @Setter String username;
|
private @Getter @Setter String username;
|
||||||
private @Getter @Setter String email;
|
private @Getter @Setter String email;
|
||||||
@@ -248,10 +252,6 @@ class AccountQueryParams extends PagingAndSortingQueryParams {
|
|||||||
}
|
}
|
||||||
return this.createTimeEnd.plusDays(1);
|
return this.createTimeEnd.plusDays(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PagingParams buildPagingParams() {
|
|
||||||
return PAGING_PARAMS_BUILDER.buildPagingParams(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
Reference in New Issue
Block a user