web开发中列表查询的场景很多,接受页面参数(比如分页参数:size、current, 查询条件参数等),执行简单查询,一般用mybatis,mapper.xml文件会有很多的if else,确实很痛苦,幸好有个mybatis-plus帮我们解决了很多问题,page对象暴露了Map<String,Object>condition这个属性,可以通过接受页面简单的字段名和字段值,通过默认“=”来组装条件,但对于稍微复杂点的比如like,大于、小于等就没有办法了,又要去写xml了。 今天稍微闲点,整一下这个问题: 首先分析一下: 简单查询一条件一般是个简单的键值对应关系,用springmvc可以用Map来接收页面参数,可不可以在key值或value值来做个文章,在key或value值中把逻辑符带进来,显然通过value值带进来不是很好的办法,可以通过key+逻辑符的方式把逻辑符带进来,如:createDate_lg "2018-06-03" 。 贴上代码:
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import io.znoo.cray.common.entity.User;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
@Slf4j
@Data
public class PageWrapperHandler<T> {
private Page<T> page = new Page<T>();
private EntityWrapper<T> wrapper = new EntityWrapper<T>();
private Map<String, Object> params;
public PageWrapperHandler(Map<String, Object> params){
this.params = params;
}
public PageWrapperHandler handle(){
page.setSize(Integer.parseInt(params.getOrDefault("size",10).toString()));
page.setCurrent(Integer.parseInt(params.getOrDefault("current", 1).toString()));
String orderByField = params.getOrDefault("orderByField", "").toString();
if (StringUtils.isNotEmpty(orderByField)) {
page.setOrderByField(orderByField);
}
Boolean isAsc = Boolean.parseBoolean(params.getOrDefault("isAsc", Boolean.TRUE).toString());
page.setAsc(isAsc);
params.remove("size");
params.remove("current");
params.remove("orderByField");
params.remove("isAsc");
wrapper.where(" 1=1 ");
Method method = null;
for (Map.Entry<String, Object> param : params.entrySet()) {
String key = param.getKey();
Object value = param.getValue();
int pos = key.lastIndexOf("_");
if(pos > -1 ){
String op = key.substring(pos + 1);
key = key.substring(0, pos);
try {
method = EntityWrapper.class.getMethod(op, String.class, Object.class);
this.wrapper = (EntityWrapper<T>) method.invoke(wrapper, key, value);
} catch (NoSuchMethodException e) {
log.error("wrapper has no such method: {0}", method.getName() );
} catch (IllegalAccessException e) {
log.error("invoke wrapper method: {0} occurs IllegalAccessException. message is {1} ", method.getName(), e.getMessage() );
} catch (InvocationTargetException e) {
log.error("invoke wrapper method: {0} occurs InvocationTargetException. message is {1}", method.getName(), e.getMessage() );
}
}else{
this.wrapper = (EntityWrapper<T>) wrapper.eq(key, value);
}
}
return this;
}
}
PageWrapperHandler处理页面参数,生成分页对象page和条件包装对象EntityWrapper.,通过反射调用Wrapper的方法。 controller层调用:
@GetMapping("/findByConditions")
public RetEntity<Page<User>> findByConditions(@RequestParam Map<String, Object> params) {
PageWrapperHandler handler = new PageWrapperHandler(params).handle();
return RetEntity.ok().setBody(userService.selectPage(handler.getPage(), handler.getWrapper()));
}
查询结果: