对于前端页面提交的数据信息,后台程序要去掉字符串前后面的空格,即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
*/
@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。