zoukankan      html  css  js  c++  java
  • 一劳永逸!!利用拦截器全局实现Mybatisplus去除字符串空格

    用户提交的数据信息,要去掉字符串前后面的空格,即TRIM,绝大多数企业应用都需要。

    一个一个改?

    太麻烦了!

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

    一个一个改?

    太麻烦了!

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

    mybatisplus或mybatis的数据库操作,主要体现在update和query两个方法上,见下面mybatis-**.jar的Executor接口。

    我们所需要的拦截的,也是这个接口所定义的CRUD操作方法。

    mybatis的拦截器同样定义在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。

  • 相关阅读:
    @ConfigurationProperties与@Value区别
    @ConfigurationProperties 注解使用姿势,这一篇就够了
    yml基本语法
    IDEA中自动导包设置及自动导包快捷键
    Mac安装JDK1.8详细教程
    Mac Safari 个人收藏夹如何使用?怎么管理?
    sql server分布式alwaysOn
    SQL Server数据库损坏、检测以及简单的修复办法【转】
    (4.44)sql server中的serverproperty
    sql server导出到excel错误:未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序
  • 原文地址:https://www.cnblogs.com/buguge/p/13749101.html
Copyright © 2011-2022 走看看