一劳永逸!!利用拦截器全局实现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 } }
插入数据的拦截器处理
插入数据\修改数据统一拦截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(); } }
测试
下面testcase用来查询数据。同样插入也OK。
当看到一些不好的代码时,会发现我还算优秀;当看到优秀的代码时,也才意识到持续学习的重要!--buguge
本文来自博客园,转载请注明原文链接:https://www.cnblogs.com/buguge/p/13749101.html