# 1.1 功能介绍

全局设置创建人更新人创建时间更新时间等字段

# 1.2 方案解析

# 1.2.1 基于mybatis-mapper的 io.mybatis.provider.SqlSourceCustomize 扩展点实现

通过自定义SqlSource的getBoundSql实现

  1. 实现SqlSourceCustomize接口,并扩展SqlSource
package com.l1yp.mybatis.mapper;

@Slf4j
public class CommonFieldSetterSqlSourceCustomize implements SqlSourceCustomize {
    
    private static final String CREATE_BY = "createBy";
    private static final String UPDATE_BY = "updateBy";

    private static final String CREATE_TIME = "createTime";
    private static final String UPDATE_TIME = "updateTime";


    @Override
    public SqlSource customize(SqlSource sqlSource, EntityTable entity, MappedStatement ms, ProviderContext context) {
        // 自定义SqlSource实现类,使用lambda简写
        return parameterObject -> {
            // 通过parameterObject、MappedStatement两个对象即可实现全局设置通用字段
            SqlCommandType sqlCommandType = ms.getSqlCommandType();
            if (sqlCommandType == SqlCommandType.INSERT || sqlCommandType == SqlCommandType.UPDATE) {
                MetaObject metaObject = ms.getConfiguration().newMetaObject(parameterObject);
                // AbstractModel是我项目的数据库实体的父类,内部含有createBy、createTime字段
                // TODO: 自行修改此处逻辑,如判断字段是否存在
                if (parameterObject instanceof AbstractModel<?,?> && sqlCommandType == SqlCommandType.INSERT) {
                    setCommonField(metaObject, CREATE_BY, LoginUtils.getLoginUserId());
                    setCommonField(metaObject, CREATE_TIME, LocalDateTime.now());
                }
                if (sqlCommandType == SqlCommandType.UPDATE) {
                    if (parameterObject instanceof AbstractWithUpdateModel<?>) {
                        setCommonField(metaObject, UPDATE_BY, LoginUtils.getLoginUserId());
                        setCommonField(metaObject, UPDATE_TIME, LocalDateTime.now());
                    } else {
                        // 处理非AbstractWithUpdateModel子类也需要自动填充的字段
                        if (metaObject.hasSetter(UPDATE_BY)) {
                            setCommonField(metaObject, UPDATE_BY, LoginUtils.getLoginUserId());
                        }
                        if (metaObject.hasSetter(UPDATE_TIME)) {
                            setCommonField(metaObject, UPDATE_TIME, LoginUtils.getLoginUserId());
                        }
                    }
                }

            }
            return sqlSource.getBoundSql(parameterObject);
        };
    }

    private void setCommonField(MetaObject metaObject, String field, Object value) {
        Object createBy = metaObject.getValue(field);
        if (createBy == null) {
            metaObject.setValue(field, value);
        }
    }
}
  1. 基于SPI机制,在classPath下创建META-INF/services/io.mybatis.provider.SqlSourceCustomize文件,文件内输入 io.mybatis.provider.SqlSourceCustomize 的实现类,如:com.l1yp.mybatis.mapper.CommonFieldSetterSqlSourceCustomize