mybatis-mapper/provider

你好,我基于mybatis拦截器实现了字段值的填充功能,想问下大佬有没有更好的建议?

li362692680 opened this issue · 4 comments

你好,我基于mybatis拦截器实现了字段值的填充功能,想问下大佬有没有更好的建议?我看新版本提供了MsCustomize定制化生成主键的接口,但是接口方法customize没有当前sql对应的入参,没法做字段值填充。

先参考下面图看看:
mybatis-provider处理流程 (1)

这个图没找到哪里可以获取入参

先提供一个具体方法,基于现有接口可以实现的。
定义处理参数的接口:

package io.mybatis.provider.parameter;

import io.mybatis.provider.EntityTable;
import org.apache.ibatis.builder.annotation.ProviderContext;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;

public interface ParameterProcessor {

  /**
   * 对 parameterObject 参数进行修改
   *
   * @param sqlSource       sqlSource
   * @param entity          实体类
   * @param ms              MappedStatement
   * @param context         当前接口和方法信息
   * @param parameterObject 参数
   */
  void process(SqlSource sqlSource, EntityTable entity, MappedStatement ms, ProviderContext context, Object parameterObject);

}

基于现有SqlSourceCustomize进行扩展。

package io.mybatis.provider.parameter;

import io.mybatis.provider.EntityTable;
import io.mybatis.provider.SqlSourceCustomize;
import io.mybatis.provider.util.ServiceLoaderUtil;
import org.apache.ibatis.builder.annotation.ProviderContext;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;

import java.util.List;

public class ParameterSqlSourceCustomize implements SqlSourceCustomize {

  private List<ParameterProcessor> processors = ServiceLoaderUtil.getInstances(ParameterProcessor.class);

  public void process(SqlSource sqlSource, EntityTable entity, MappedStatement ms, ProviderContext context, Object parameterObject) {
    for (ParameterProcessor processor : processors) {
      processor.process(sqlSource, entity, ms, context, parameterObject);
    }
  }

  @Override
  public SqlSource customize(SqlSource sqlSource, EntityTable entity, MappedStatement ms, ProviderContext context) {
    if (processors.isEmpty()) {
      return sqlSource;
    }
    return parameterObject -> {
      process(sqlSource, entity, ms, context, parameterObject);
      return sqlSource.getBoundSql(parameterObject);
    };
  }

}

注意SPI需要相应的service配置。

基于上述接口的实现:

package io.mybatis.provider.parameter;

import io.mybatis.provider.EntityTable;
import org.apache.ibatis.builder.annotation.ProviderContext;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.mapping.SqlSource;

public class BaseParameterProcessor implements ParameterProcessor {

  @Override
  public void process(SqlSource sqlSource, EntityTable entity, MappedStatement ms, ProviderContext context, Object parameterObject) {
    if (ms.getSqlCommandType() == SqlCommandType.INSERT || ms.getSqlCommandType() == SqlCommandType.UPDATE) {
      //比如新增插入创建人、创建时间
      //更新时更新人、更新时间
    }
  }

}