Spring Boot 使用mybatis-plus逻辑删除选装件

Spring Boot 使用mybatis-plus逻辑删除选装件

Laughing
2021-06-11 / 0 评论 / 1,688 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2021年06月11日,已超过1316天没有更新,若内容或图片失效,请留言反馈。

试想一下我们的系统,我们所有的表都有五个字段,分别是创建者(create_by)、创建时间(create_time)、修改者(update_by)、修改时间(update_time)、删除标志(del_flag), 同时通过mybatis拦截器,自动注入创建人、创建时间、修改人、修改时间。
目前在数据库新增,能自动注入创建人、创建时间,修改时,能自动注入修改人、 修改时间。如果我们调用mybatis-plus提供的删除方法(deleteById),既然是逻辑删除,我们设想的肯定是此时能够自动注入修改人、修改时间,但是,实际测试你会发现,此时sql并没有注入修改人、修改时间。
为了解决这个问题,mybatis-plus提供了一个LogicDeleteByIdWithFill的逻辑删除组装件。通过此方法,我们在进行逻辑删除时,便能自动注入修改人、修改时间。

继承DefaultSqlInjector

/**
 * Description:官方逻辑删除选装件
 *
 * @author : laughing
 * DateTime: 2021-06-11 15:21
 */
@Component
public class MySqlInjector extends DefaultSqlInjector {

    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
        List<AbstractMethod> methodList = super.getMethodList(mapperClass);
        //2.官方选装件,逻辑删除时,自动填充其他字段(例如逻辑删除时,自动填充删除人是谁,什么时候删除的)
        methodList.add(new LogicDeleteByIdWithFill());
        return methodList;
    }
}

配置逻辑删除插件

/**
 * Mybatis-Plus配置
 *
 * @author laughing
 */
@Configuration
@EnableTransactionManagement
public class MyBatisPlusConfig {

    @javax.annotation.Resource
    private Environment env;

    static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";

    private final Logger logger = LoggerFactory.getLogger(MyBatisPlusConfig.class);

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 如果用了分页插件注意先 add TenantLineInnerInterceptor 再 add PaginationInnerInterceptor
        // 用了分页插件必须设置 MybatisConfiguration#useDeprecatedExecutor = false
        // interceptor.addInnerInterceptor(new PaginationInnerInterceptor());

        interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(
                new TenantLineHandler() {
                    // manager_id = 1088248166370832385

                    // 获取租户 ID 值表达式,只支持单个 ID 值
                    @Override
                    public Expression getTenantId() {
                        return new StringValue(SecurityUtils.getOrgCode());
                    }

                    // 这是 default 方法,默认返回 false 表示所有表都需要拼多租户条件,
                    // 这里设置 role表不需要该条件
                    @Override
                    public boolean ignoreTable(String tableName) {
                        logger.info("orgCode=======" + SecurityUtils.getOrgCode());
                        return StringUtils.isEmpty(SecurityUtils.getOrgCode()) || WisdomAgricultureConfig.getFilterTableList().stream().anyMatch(e -> e.equalsIgnoreCase(tableName));
                    }

                    @Override
                    public String getTenantIdColumn() {
                        return "org_code";
                    }

                }));
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }

    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        return configuration -> configuration.setUseDeprecatedExecutor(false);
    }

    public static String setTypeAliasesPackage(String typeAliasesPackage) {
        ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver();
        MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
        List<String> allResult = new ArrayList<String>();
        try {
            for (String aliasesPackage : typeAliasesPackage.split(",")) {
                List<String> result = new ArrayList<String>();
                aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
                        + ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN;
                Resource[] resources = resolver.getResources(aliasesPackage);
                if (resources != null && resources.length > 0) {
                    MetadataReader metadataReader = null;
                    for (Resource resource : resources) {
                        if (resource.isReadable()) {
                            metadataReader = metadataReaderFactory.getMetadataReader(resource);
                            try {
                                result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());
                            } catch (ClassNotFoundException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
                if (result.size() > 0) {
                    HashSet<String> hashResult = new HashSet<String>(result);
                    allResult.addAll(hashResult);
                }
            }
            if (allResult.size() > 0) {
                typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0]));
            } else {
                throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return typeAliasesPackage;
    }

    public Resource[] resolveMapperLocations(String[] mapperLocations) {
        ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
        List<Resource> resources = new ArrayList<Resource>();
        if (mapperLocations != null) {
            for (String mapperLocation : mapperLocations) {
                try {
                    Resource[] mappers = resourceResolver.getResources(mapperLocation);
                    resources.addAll(Arrays.asList(mappers));
                } catch (IOException e) {
                    // ignore
                }
            }
        }
        return resources.toArray(new Resource[resources.size()]);
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        String typeAliasesPackage = env.getProperty("mybatis-plus.typeAliasesPackage");
        String mapperLocations = env.getProperty("mybatis-plus.mapperLocations");
        String configLocation = env.getProperty("mybatis-plus.configLocation");
        typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
        VFS.addImplClass(SpringBootVFS.class);
        final MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
        sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
        sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
        sessionFactory.setPlugins(mybatisSqlInterceptor(), mybatisPlusInterceptor());
        sessionFactory.setGlobalConfig(globalConfig());
        return sessionFactory.getObject();
    }


    @Bean
    public MybatisSqlInterceptor mybatisSqlInterceptor() {
        MybatisSqlInterceptor mybatisSqlInterceptor = new MybatisSqlInterceptor();
        Properties properties = new Properties();
        mybatisSqlInterceptor.setProperties(properties);
        return mybatisSqlInterceptor;
    }

    /**
     * 逻辑删除插件
     */
    @Bean
    public GlobalConfig globalConfig() {
        GlobalConfig globalConfig = new GlobalConfig();
        GlobalConfig.DbConfig dbConfig = new GlobalConfig.DbConfig();
        dbConfig.setLogicDeleteValue("Y");
        dbConfig.setLogicNotDeleteValue("N");
        globalConfig.setDbConfig(dbConfig);
        globalConfig.setSqlInjector(sqlInjector());
        return globalConfig;
    }

    /**
     * 自定义Sql注入器
     */
    @Bean
    public MySqlInjector sqlInjector() {
        return new MySqlInjector();
    }
}

扩展BaseMapper

/**
 * Description:
 *
 * @author : laughing
 * DateTime: 2021-06-11 15:23
 */
public interface MyBaseMapper<T> extends BaseMapper<T> {

    /**
     * 逻辑删除,并且带自动填充
     */
    int deleteByIdWithFill(T entity);

}

修改Mapper接口

修改Mapper接口,将原来继承BaseMapper改成我们自定义的MyBaseMapper

/**
 * Description:红外测温
 * 
 * @author : laughing
 * DateTime: 2021-05-18 10:28  
 */
public interface CulturePigTemperatureMapper extends MyBaseMapper<CulturePigTemperature> {

    /**
     * 红外测温列表查询
     * @param pig 查询条件
     * @return 结果
     */
    List<CulturePigTemperature> selectCulturePigTemperatureList(CulturePig pig);
}

修改删除方法

将原来的删除方法deleteById改成deleteByIdWithFill
再次测试,可以看到修改人、修改时间字段能够在逻辑删除方法时自动注入。

0

评论 (0)

取消