buguge - Keep it simple,stupid

知识就是力量,但更重要的,是运用知识的能力why buguge?

导航

一劳永逸!!利用拦截器全局实现Mybatisplus去除字符串空格

对于前端页面提交的数据信息,后台程序要去掉字符串前后面的空格,即TRIM,绝大多数企业应用都需要。

一个一个改?

太麻烦了!

用户在网页输入条件查询数据,同样要去掉空格,否则可能导致查不出来数据。并且,通常,我们在排查这样的问题的时候,也许只有眼明心细的人,才能发现原来是有空格字符导致的。

一个一个改?

太麻烦了!

本文介绍使用拦截器(Interceptor)来实现全局处理。mybatis自带Interceptor接口,我们只需实现接口即可。

 

mybatisplus或mybatis对于数据库CRUD操作,主要体现在mybatis jar包里 org.apache.ibatis.executor.Executor 接口的两个方法——#update 和 #query,见下面mybatis-3.5.1.jar截图。

我们所需要的拦截的,也正是这两个方法。

mybatis的拦截器是 org.apache.ibatis.plugin.Interceptor ,同样定义在mybatis jar中。

 

 

 

查询数据拦截器处理

查询数据拦截Executor.query方法。对于mybatisplus,请求参数一般是lambda表达式,所以我们对lambda表达式携带的数据进行改造。

代码如下:

package com.emaxcard.car.config;

import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.binding.MapperMethod.ParamMap;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Component;

import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

/**
 * mybatis拦截器,去掉字符串参数的前后空格
 *
 * @Author gz.zhang
 * @Date 2020-09-29
 * @see {https://www.cnblogs.com/buguge/p/13749101.html}
 */
@Slf4j
@Component
@Intercepts({
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class})})
public class MybatisQueryInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        String sqlId = mappedStatement.getId();
        log.debug("------sqlId------" + sqlId);
        SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
        log.debug("------sqlCommandType------" + sqlCommandType);

        Object parameter = invocation.getArgs()[1];
        if (parameter == null || SqlCommandType.SELECT != sqlCommandType) {
            return invocation.proceed();
        }

        if (parameter instanceof ParamMap
                && ((ParamMap) parameter).get("ew") instanceof AbstractWrapper) {
            Map nameValuePairs = ((AbstractWrapper) ((ParamMap) parameter).get("ew")).getParamNameValuePairs();

            Iterator<Map.Entry<String, Object>> iterator = nameValuePairs.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, Object> next = iterator.next();
                if (next.getValue() instanceof String) {
                    next.setValue(((String) next.getValue()).trim());
                }
            }
        }

        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        // TODO Auto-generated method stub
    }

}
View Code

 

插入数据的拦截器处理

插入数据\修改数据统一拦截Executor.update方法。请求参数一般是pojo对象,利用反射来修改属性的值。

关键代码如下: 

@Slf4j
@Component
@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
public class MybatisInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        String sqlId = mappedStatement.getId();
        log.debug("------sqlId------" + sqlId);
        SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
        Object parameter = invocation.getArgs()[1];
        log.debug("------sqlCommandType------" + sqlCommandType);

        if (parameter == null) {
            return invocation.proceed();
        }
        if (SqlCommandType.INSERT == sqlCommandType || SqlCommandType.UPDATE == sqlCommandType) {
            Field[] fields = oConvertUtils.getAllFields(parameter);
            for (Field field : fields) {
                if (field.getType().equals(String.class)) {
                    field.setAccessible(true);
                    Object o = field.get(parameter);
                    field.setAccessible(false);
                    String newVal = o == null ? "" : String.valueOf(o).trim();
                    field.setAccessible(true);
                    field.set(parameter, newVal);
                    field.setAccessible(false);
                }
            }
        }
        
        return invocation.proceed();
    }

}
View Code

 

 

测试

下面testcase用来查询数据。同样插入也OK。

 

posted on 2020-09-29 13:02  buguge  阅读(7160)  评论(0编辑  收藏  举报