1. 自定义插件 CharEscapeInnerInterceptor
,继承InnerInterceptor
import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import lombok.SneakyThrows;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import javax.annotation.PostConstruct;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
/**
* @author : yx-0176
* @description
* @date : 2021/12/6
*/
public class CharEscapeInnerInterceptor implements InnerInterceptor {
Logger log = LoggerFactory.getLogger(CharEscapeInnerInterceptor.class);
private CharEscape charEscape = new CharEscapeImpl();
public CharEscapeInnerInterceptor() {
}
public CharEscapeInnerInterceptor(CharEscape charEscape) {
this.charEscape = charEscape;
}
@PostConstruct
public void init() {
log.info("CharEscapeInnerInterceptor is plugins of mybatis-plus initd");
}
@SneakyThrows
@Override
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
log.info("CharEscapeInnerInterceptor is plugins of mybatis-plus paramer before update: {}", parameter.toString());
if (parameter instanceof MapperMethod.ParamMap) {
MapperMethod.ParamMap map = (MapperMethod.ParamMap) parameter;
for (Object key : map.keySet()) {
Object obj = map.get(key);
if (obj != null) {
if (obj instanceof AbstractWrapper) {
// Mybatis-plus的Wrapper查询参数lambda
getObjCharEscape(((AbstractWrapper) obj).getParamNameValuePairs());
// Mybatis-plus的Wrapper查询参数
getObjCharEscape(((AbstractWrapper) obj).getEntity());
} else {
getObjCharEscape(obj);
}
}
}
} else if (parameter instanceof String) {
getObjCharEscape(parameter);
}
log.info("CharEscapeInnerInterceptor is plugins of mybatis-plus paramer after update:{}", parameter);
}
public Object getObjCharEscape(Object object) throws Exception {
if (object instanceof Long) {
return object;
}
if (object instanceof String) {
// 反射修改参数值
Field f = object.getClass().getDeclaredField("value");
f.setAccessible(true);
f.set(object, charEscape.charEscape(object.toString()).toCharArray());
return object;
}
if (object instanceof Map) {
Map map = (Map) object;
for (Object o : map.keySet()) {
map.put(o.toString(), getObjCharEscape(map.get(o)));
}
return map;
}
if (object instanceof Collection) {
for (Object o : ((Collection) object)) {
getObjCharEscape(o);
}
return object;
}
for (Field field : object.getClass().getDeclaredFields()) {
field.setAccessible(true);
// 判断是否为final
if (Modifier.isFinal(field.getModifiers())) {
continue;
}
Object o = field.get(object);
if (Objects.isNull(field.get(object))) {
continue;
}
field.set(object, getObjCharEscape(o));
}
return object;
}
public interface CharEscape {
/**
* 转义方法
*
* @param charString 需要转义的字字符
* @return
*/
String charEscape(String charString);
}
private class CharEscapeImpl implements CharEscape {
@Override
public String charEscape(String charString) {
if (!StringUtils.hasLength(charString)) {
return charString;
}
charString = charString.trim();
if (charString.contains("\\")) {
charString = charString.replaceAll("\\\\", "\\\\");
}
if (charString.contains("%")) {
charString = charString.replaceAll("%", "\\\\%");
}
if (charString.contains("_")) {
charString = charString.replaceAll("_", "\\\\_");
}
return charString;
}
}
}
2. 实现字符转义类
默认是CharEscapeImpl ()这个类中方法进行字符转义,也可以自定义实现类进行字符转义
public class TestCharEscape implements CharEscapeInnerInterceptor.CharEscape {
@Override
public String charEscape(String charString) {
// 实现转义
return "1";
}
}
3. 修改mybatis配置 ,添加拦截器
CharEscapeInnerInterceptor
有两个构造方法
3.1 无参
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
interceptor.addInnerInterceptor(new CharEscapeInnerInterceptor());
return interceptor;
}
}
3.2 自定义转义实现类
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
interceptor.addInnerInterceptor(new CharEscapeInnerInterceptor(new TestCharEscape ()));
return interceptor;
}
}
4. 测试
结果:传入参数为%
,查询时sql参数为\%
,参数已转义