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) //不是用等于查找条件,需要指定type
private 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中增加一处属性和注解即可,不用再复制一段雷同的代码