MyBatis-Plus使用通配符组装QueryWrapper条件构造器

8 篇文章 0 订阅
4 篇文章 0 订阅

1、前端输入指定的约束条件字符进行查询,使如输入6010*或6010%,则查出以6010开头的信息,等等,后端接收Json body进行组装QueryWrapper条件构造器

   QueryWrapperConverter.class

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 组装MyBatis-Plus条件构造器,前提条件数据库字段名与json对象属性名必须定义规范
 * @author KingLee
 * @since 1.0
 * @param <T>
 */
public class QueryWrapperConverter<T> {

    private static final String LIKE_SQL_KEY = "%";

    private static final String PLACEHOLDER_SQL_KEY = "*";

    private static final String EQ_SQL_KEY = "=";

    private static final String NE_SQL_KEY = "!=";

    private static final String NULL_SQL_KEY = "~null~";

    private static final String NOT_NULL_SQL_KEY = "!=~null~";

    private static final String SPLIT_SQL_KEY = ",";

    private static final String GT_SQL_KEY = ">";

    private static final String GE_SQL_KEY = ">=";

    private static final String LT_SQL_KEY = "<";

    private static final String LE_SQL_KEY = "<=";

    private static final String BETWEEN_SQL_KEY = "between";

    private static final String NOT_BETWEEN_SQL_KEY = "notBetween";

    private static final String AND_SQL_KEY = "and";

    private static final String SWITCH_MATCHES_REGULAR = "[a-z]+[A-Z][a-z]+([A-Z][a-z]+)*";

    private static Pattern pattern = Pattern.compile("[A-Z]");

    /**
     * 判断通配符组装MyBatis-Plus条件构造器
     * @param queryWrapper 对象条件构造器
     * @param queryObject json对象
     * @param <T>
     */
    public static<T> void converter(QueryWrapper<T> queryWrapper, Object queryObject) {
        // reflect获取实体类的所有属性信息,返回Fields数组
        Field[] fields = queryObject.getClass().getDeclaredFields();
        int fieldLength = fields.length;
        while (fieldLength-- > 0) {
            //属性名
            String fieldName = fields[fieldLength].getName();
            //属性值
            String fieldValue = getFieldValueByFieldName(fieldName, queryObject);
            //表字段名
            String dbFieldName = switchFieldNameToColumnName(fieldName);

            if (StringUtils.isEmpty(fieldValue)) {
                continue;
            }
            //以*或%结尾
            if (fieldValue.endsWith(LIKE_SQL_KEY) || fieldValue.endsWith(PLACEHOLDER_SQL_KEY)) {
                queryWrapper.likeLeft(dbFieldName, fieldValue.replace(LIKE_SQL_KEY, "").replace(PLACEHOLDER_SQL_KEY, ""));
            }
            //以*或%开头
            else if (fieldValue.startsWith(LIKE_SQL_KEY) || fieldValue.startsWith(PLACEHOLDER_SQL_KEY)) {
                queryWrapper.likeRight(dbFieldName, fieldValue.replace(LIKE_SQL_KEY, "").replace(PLACEHOLDER_SQL_KEY, ""));
            }
            //以=开头,完成匹配
            else if (fieldValue.startsWith(EQ_SQL_KEY)) {
                queryWrapper.eq(dbFieldName, fieldValue.replace(EQ_SQL_KEY, ""));
            }
            //以!=开头,完成不匹配
            else if (fieldValue.startsWith(NE_SQL_KEY)) {
                queryWrapper.ne(dbFieldName, fieldValue.replace(NE_SQL_KEY, ""));
            }
            //~null~表示空值
            else if (fieldValue.startsWith(NULL_SQL_KEY)) {
                queryWrapper.isNull(dbFieldName);
            }
            //!=~null~表示搜索非空值
            else if (fieldValue.startsWith(NOT_NULL_SQL_KEY)) {
                queryWrapper.isNotNull(dbFieldName);
            }
            //如果有逗号,则以逗号折开,拼or连接
            else if (fieldValue.contains(SPLIT_SQL_KEY)) {
                String[] splitValue = fieldValue.split(SPLIT_SQL_KEY);
                StringBuffer applySql = new StringBuffer();
                for (String value : splitValue) {
                    applySql.append(dbFieldName + " like '" + value + "%' or ");
                }
                String finalApplySql = applySql.substring(0,applySql.length()-3);
                queryWrapper.and(wrapper->wrapper.apply(finalApplySql));
            }
            //如果有>,则以>去做比较
            else if (fieldValue.contains(GT_SQL_KEY) && !fieldValue.contains(GE_SQL_KEY)) {
                queryWrapper.gt(dbFieldName, fieldValue.replace(GT_SQL_KEY, ""));
            }
            //如果有>=,则以>=去做比较
            else if (fieldValue.contains(GE_SQL_KEY)) {
                queryWrapper.ge(dbFieldName, fieldValue.replace(GE_SQL_KEY, ""));
            }
            //如果有<,则以<去做比较
            else if (fieldValue.contains(LT_SQL_KEY) && !fieldValue.contains(LE_SQL_KEY)) {
                queryWrapper.lt(dbFieldName, fieldValue.replace(LT_SQL_KEY, ""));
            }
            //如果有<=,则以<=去做比较
            else if (fieldValue.contains(LE_SQL_KEY)) {
                queryWrapper.le(dbFieldName, fieldValue.replace(LE_SQL_KEY, ""));
            }
            //如果有between...and...
            else if (fieldValue.toLowerCase().contains(BETWEEN_SQL_KEY)
                    && fieldValue.toLowerCase().contains(AND_SQL_KEY)) {
                String startValue = fieldValue.substring(7, fieldValue.indexOf(AND_SQL_KEY));
                String endValue = fieldValue.substring(fieldValue.indexOf(AND_SQL_KEY) + 3, fieldValue.length());
                queryWrapper.between(dbFieldName, startValue.trim(), endValue.trim());
            }
            //如果有notBetween...and...
            else if (fieldValue.toLowerCase().contains(NOT_BETWEEN_SQL_KEY.toLowerCase())
                    && fieldValue.toLowerCase().contains(AND_SQL_KEY)) {
                String startValue = fieldValue.substring(10, fieldValue.indexOf(AND_SQL_KEY));
                int lastLetter = fieldValue.indexOf(AND_SQL_KEY) + 3;
                String endValue = fieldValue.substring(lastLetter, fieldValue.length());
                queryWrapper.notBetween(dbFieldName, startValue.trim(), endValue.trim());
            }
            //没有通配符,则模糊查询
            else {
                queryWrapper.like(dbFieldName, fieldValue);
            }
        }
    }

    /**
     * reflect根据类对象属性名获取属性值
     * @param fieldName
     * @param object
     * @return
     */
    public static String getFieldValueByFieldName(String fieldName, Object object) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = object.getClass().getMethod(getter, new Class[] {});
            Object value = method.invoke(object, new Object[] {});
            return value.toString();
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            return null;
        }
    }

    /**
     * 根据骆峰属性名转成数据库表对应字段名
     * @e.g. companyName->company_name
     * @param fieldName
     * @return
     */
    public static String switchFieldNameToColumnName(String fieldName) {
        if (fieldName.matches(SWITCH_MATCHES_REGULAR)){
            Matcher matcher = pattern.matcher(fieldName);
            while(matcher.find()){
                String oldLetter = matcher.group();
                String newLetter = matcher.group().toLowerCase();
                fieldName = fieldName.replaceAll(oldLetter, "_" + newLetter);
            }
        }
        return fieldName;
    }
}

2、 Vo类SapUnitQuery.class,负责RequestBody传输

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.mywind.qingyun.common.PageDo;
import com.mywind.qingyun.mdm.pojo.MdmSapUnit;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.util.Date;

/**
 * @author KineLee
 * @since 1.0
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class SapUnitQuery extends PageDo {

   @ApiModelProperty(value = "主键id")
   private String id;

   @ApiModelProperty(value = "度量单位代码")
   private String unitCode;

   @ApiModelProperty(value = "度量单位文本")
   private String unitDescription;

   @ApiModelProperty(value = "创建时间")
   private String createTime;

}

3、 Service层分页访问

/**
     * 分页查询单位列表
     * @param unitQuery
     * @return
     */
    @Override
    public ResultDo listUnit(SapUnitQuery unitQuery) {
        Page<MdmSapUnit> page = new Page<>(unitQuery.getPageNumber(), unitQuery.getPageSize());
        QueryWrapper<MdmSapUnit> queryWrapper = new QueryWrapper<>();
        QueryWrapperConverter.converter(queryWrapper,unitQuery);
        return ResultDo.ok(this.page(page, queryWrapper));
    }

4、分页辅助类

import lombok.Data;

import java.io.Serializable;
/**
 * @author KingLee
 */
@Data
public class PageDo implements Serializable {

    private static final long serialVersionUID = 1L;

    private int pageNumber;

    private int pageSize;

    private String sort;

    private String order;

}

 

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值