一、为什么要对查询条件做一定的封装
通常的开发规范下,我们使用GET请求获取资源,而GET请求一般不采用请求体传参,而是使用@RequestParam,虽然请求体传参并非不可行。本文从实际的用户端服务开发场景出发(管理端服务不提,因为大多数情况下有现成的开发脚手架,方便快捷就好),将采用Map接收的多条件列表查询和多条件分页查询的参数进行封装,使得查询条件可以易于维护和管理,也在某种意义上,实现了使用body传递查询参数的目的。
因为Map的对参数的模糊性,我们在维护的时候无法得知其中的具体参数,如果没有文档,则要进行代码的摸索,且以【参数 = map.get("参数名") 】的形式在ServiceImpl的列表查询方法中获取,没有抽离出独立的方法进行维护,未免不太优雅,于是对查询条件的统一管理便显得势在必行。
二、封装的思路
一般来说,用户端的数据列表不做分页处理,而是使用瀑布流,但是在底层,瀑布流还是分页,只不过是对数据列表进行了不同形式的展现。本文针对用户端展开,我们可以定义一个基础参数类,里面放置分页参数属性,要求每个需要分页的接口所对应的查询条件类都继承这个基础参数类,然后在列表查询接口的查询条件类中维护自身独有的所有查询条件,这是其一。
接下来我们需要定义一个查询条件处理接口,要求每个需要列表查询的业务实现类都实现这个接口,并实现其中的条件处理方法,对本业务类中需要的查询条件进行构造,此条件处理接口还应当提供默认方法,默认初始化基础条件类中的分页参数,减少重复代码的书写。
三、核心代码
1.基础条件类BaseCondition
/**
* @author ghCode
* @since 2023-09-14 19:57
* 分页参数基础类,所有condition查询条件实体都要继承
*/
@Data
public class BaseCondition {
/**
* 当前页数
*/
private Integer page;
/**
* 每页条数
*/
private Integer size;
}
2.条件处理接口
/**
* @author ghCode
* @since 2023-09-14 19:54
* 查询条件处理接口,所有需要分页(含瀑布流)查询的service都要继承
*/
public interface IConditionWrapper<T extends BaseCondition> {
/**
* 处理参数的方法,由各个service层实现类实现该接口,封装自定义扩展的查询条件
*
* @param params 参数
* @return 条件实体
*/
T handleParams(Map<String, Object> params);
/**
* 默认方法,处理分页参数,当查询除分页外无其他条件时,使用该方法默认实现handlerParams()方法即可
* 发生异常则抛出"对象实例化异常"
*
* @param params 参数
* @return 条件实体
*/
default T pageWrapper(Map<String, Object> params, Class<T> conditionClass) {
Integer page = (params.get("page") != null) ? (Integer) params.get("page") : 1;
Integer size = (params.get("size") != null) ? (Integer) params.get("size") : 20;
T t = null;
try {
t = conditionClass.newInstance();
t.setPage(page);
t.setSize(size);
} catch (Exception e) {
throw new SystemException(ExceptionEnum.INSTANT_FAIL);
}
return t;
}
}
三、总结
如果你耐心的看到此处,那么我相信你一定知道了作者这么做的用意,如果有更好的思路和方式,请在评论区告诉作者,大家一起讨论,一起进步!