Mybatis plus 如何自定义拦截器过滤Stirng类型字段值首尾空格?

需求:
自定义拦截器过滤Stirng类型字段值首尾空格

根据下列代码遇到的问题:

  • 如果是实体不知道是否有下列代码更好的处理办法
  • 如果是LambdaUpdateWrapper或UpdateWrapper,该如果获取每个字段过滤掉首位空格

以下是实现Mybatis plus的InnerInterceptor接口

public class StringSpacesInterceptor implements InnerInterceptor {

    private final boolean wrapperMode;

    public StringSpacesInterceptor() {
        this(false);
    }

    public StringSpacesInterceptor(boolean wrapperMode) {
        this.wrapperMode = wrapperMode;
    }

    @Override
    public void beforeUpdate(Executor executor, MappedStatement mappedStatement, Object parameter) throws SQLException {
        if (SqlCommandType.UPDATE != mappedStatement.getSqlCommandType() &&
            SqlCommandType.INSERT != mappedStatement.getSqlCommandType()) {
            return;
        }

        if (parameter instanceof Map) {
            Map<String, Object> map = (Map<String, Object>) parameter;
            spacesHandle(map, mappedStatement.getId());
        }
    }

    @SneakyThrows
    protected void spacesHandle(Map<String, Object> map, String msId) {
        Object et = map.getOrDefault(Constants.ENTITY, null);
        if (null != et) {
            TableInfo tableInfo = TableInfoHelper.getTableInfo(et.getClass());
            if (null != tableInfo) {
                List<TableFieldInfo> fieldList = tableInfo.getFieldList();
                if (null != fieldList && !fieldList.isEmpty()) {
                    for (TableFieldInfo tableFieldInfo : fieldList) {
                        if (!String.class.equals(tableFieldInfo.getPropertyType())) {
                            continue;
                        }
                        Field fieldInfo = tableFieldInfo.getField();
                        fieldInfo.setAccessible(true);
                        Object value = fieldInfo.get(et);
                        fieldInfo.set(et, ((String) value).trim());
                    }
                }
            }
        }
        // update(LambdaUpdateWrapper) or update(UpdateWrapper)
        else if (wrapperMode && map.entrySet().stream().anyMatch(t -> Objects.equals(t.getKey(), Constants.WRAPPER))) {
            // TODO 这里不知道怎么处理了......
        }
    }
}

搜索相关资料没有通过拦截器全局处理Mybatis plus字段前后空格问题的。难受。

希望大佬补充代码学习下....

阅读 1.1k
3 个回答

之前也有这样的需求,然后通过注解配合拦截器实现,如果需要改造成全局,稍加修改也行。

我直接贴代码了。

@Intercepts(@Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class}))
@SuppressWarnings({"SpringJavaInjectionPointsAutowiringInspection","rawtypes"})
public class EntityFieldRtrimInterceptor implements Interceptor {

    private final String typeAliasesPackage;

    @Autowired
    public EntityFieldRtrimInterceptor(String typeAliasesPackage) {
        this.typeAliasesPackage = typeAliasesPackage;
    }

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object obj = invocation.proceed();
        if (obj instanceof Integer) {
            return obj;
        } else if (obj instanceof List) {
            List<?> list = (List) obj;
            list.forEach(e -> fieldRtrim(e, typeAliasesPackage));
        } else {
            fieldRtrim(obj, typeAliasesPackage);
        }
        return obj;
    }

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

    @Override
    public void setProperties(Properties properties) {

    }

    private void fieldRtrim(Object bean, String pkgName) {
        if (bean != null && bean.getClass().getPackage().getName().startsWith(pkgName)) {
            Field[] fields = bean.getClass().getDeclaredFields();
            for (Field field : fields) {
                String pkg = field.getType().getPackage().getName();
                if (pkg.startsWith(String.class.getPackage().getName())) {
                    if (Arrays.stream(field.getDeclaredAnnotations()).anyMatch(e -> e instanceof Rtrim)) {
                        String value = (String) ReflectHelper.getFieldValue(bean, field.getName());
                        if (value != null) {
                            ReflectHelper.setFieldValue(bean, field.getName(), value.replaceFirst("\\s+$", ""));
                        }
                    }
                } else if (pkg.startsWith(pkgName)) {
                    fieldRtrim(ReflectHelper.getFieldValue(bean, field.getName()), pkgName);
                }
            }
        }
    }

}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
public @interface Rtrim {
}

mybatis通过TypeHandler去处理参数的,你网上搜搜怎么用就行了
image.png

https://mybatis.ac.cn/mybatis-3/configuration.html#typehandlers
你可以覆盖类型处理器或创建自己的类型处理器来处理不受支持或非标准类型。为此,实现接口 org.apache.ibatis.type.TypeHandler 或扩展便捷类 org.apache.ibatis.type.BaseTypeHandle.

package org.apache.ibatis.type;
/**
 * @author Clinton Begin
 */
public class StringTypeHandler extends BaseTypeHandler<String> {

  @Override
  public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
      throws SQLException {
    ps.setString(i, parameter);
  }

  @Override
  public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
    return rs.getString(columnName);
  }

  @Override
  public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
    return rs.getString(columnIndex);
  }

  @Override
  public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
    return cs.getString(columnIndex);
  }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏