Springboot+Mybatis实现条件查询可以这样实现
@Data
@NoArgsConstructor
@ApiModel("查询DTO")
public class QueryDTO {@ApiModelProperty("名称")private String name;@ApiModelProperty("类型")private String type;@ApiModelProperty("描述")private String description;}
Controller代码如下
@GetMapping("/list")@ApiOperation(value = "列表查询")public Result list(@ApiParam QueryDTO request){QueryWrapper queryWrapper = new QueryWrapper<>();if(request.getName()!=null){queryWrapper.like("name",request.getName());}if(request.getType()!=null){queryWrapper.eq("type",request.getType());}if(request.getDescription()!=null){queryWrapper.eq("descrption",request.getDescription());}List list = service.list(queryWrapper);return Result.success(list);}
可见,每多一个条件,就要多写一段 queryWrapper.eq...这样类似的代码
使用自定义注解可以更优雅的实现条件查询
添加一个自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Query {/*** 对应数据库字段,为空取实体属性名 驼峰转下划线*/String column() default "";/*** 另一个类中的属性名称,支持多级获取,以小数点隔开*/String targetAttr() default "";/*** 查询类型*/Type type() default Type.EQUAL;enum Type {/*** 相等*/EQUAL((queryWrapper, filedColumn, val) -> {queryWrapper.eq(filedColumn, val);}),/*** 大于等于*/GREATER_THAN((queryWrapper, filedColumn, val) -> {queryWrapper.ge(filedColumn, val);}),/*** 大于*/GREATER_THAN_NQ((queryWrapper, filedColumn, val) -> {queryWrapper.gt(filedColumn, val);}),/*** 小于等于*/LESS_THAN((queryWrapper, filedColumn, val) -> {queryWrapper.le(filedColumn, val);}),/*** 小于*/LESS_THAN_NQ((queryWrapper, filedColumn, val) -> {queryWrapper.lt(filedColumn, val);}),/*** 不等于*/NOT_EQUAL((queryWrapper, filedColumn, val) -> {queryWrapper.ne(filedColumn, val);}),/*** 不为空*/NOT_NULL((queryWrapper, filedColumn, val) -> {queryWrapper.isNotNull(filedColumn);}),/*** 中模糊查询
* like %str%*/LIKE((queryWrapper, filedColumn, val) -> {queryWrapper.like(filedColumn, val);}),/*** 左模糊查询*/LEFT_LIKE((queryWrapper, filedColumn, val) -> {queryWrapper.likeLeft(filedColumn, val);}),/*** 右模糊查询*/RIGHT_LIKE((queryWrapper, filedColumn, val) -> {queryWrapper.likeRight(filedColumn, val);}),/*** 包含*/IN((queryWrapper, filedColumn, val) -> {queryWrapper.in(filedColumn, (Collection) val);}),/*** JSON数组中是否包含*/JSON_ARRAY_CONTAINS((queryWrapper, filedColumn, val) -> {queryWrapper.apply("JSON_CONTAINS(" + filedColumn + ",json_array({0}) )", val);}),;private TriConsumer consumer;Type(TriConsumer consumer) {this.consumer = consumer;}public void buildQuery(QueryWrapper t, String field, Object val) {consumer.accept(t, field, val);}}
}
如果字段名与属性名相同或相匹配(驼峰转下划线 如:createTime-> create_time 表示字段匹配),不用标注column字段 如果字段名与属性名不同且不匹配,如属性名为 searchValue,需要查询的字段是name,则需要增加column字段,@Query(column="name")默认使用=查询,如果要使用like或其它查询类型,则需要标注type字段,选择相应的type即可,如: @Query(type=Query.Type.LIKE) 每个type会生成什么样的QueryWrapper语句,可以参考Type枚举类的方法
再添加一个处理注解的工具类
@Slf4j
public class QueryUtil {public static QueryWrapper setQueryWrapper(T bean) {QueryWrapper queryWrapper = new QueryWrapper<>();if (bean == null) {return queryWrapper;}try {List
在查询的DTO类中使用注解
@Data
@NoArgsConstructor
@ApiModel("查询DTO")
public class QueryDTO {/*** 名称*/@ApiModelProperty("名称")@Query(type = Query.Type.LIKE) //不是用等于查找条件,需要指定typeprivate String name;/*** 类型*/@ApiModelProperty("类型")@Query //表字段与属性名相匹配,且是用等于查找的,只需要这样的简单注解即可private String type;/*** 描述*/@ApiModelProperty("描述")@Query(column="description") //如果字段名与属性名不匹配,则添加column字段值指定表字段private String description;}
Controller类中使用如下:
@GetMapping("/list")@ApiOperation(value = "列表查询")public Result list(@ApiParam QueryDTO request){QueryWrapper queryWrapper = QueryUtil.setQueryWrapper(request);List list = service.list(queryWrapper);return Result.success(list);}
Controller中的代码更简洁了,如果需要增加一个条件,只需要在QueryDTO中增加一处属性和注解即可,不用再复制一段雷同的代码