MyBatis-Plus(3) 自定义逻辑删除插件(全局处理xml中的SQL)

一、前言

MyBatis-Plus原本是提供了逻辑删除的功能。

在这里插入图片描述

但如果在xml中直接写sql,它的逻辑删除是未生效的。 网上看了下,未找到这一解决方案... 下面我们来自定义一个简单的逻辑删除插件来实现这一功能^_^

二、自定义逻辑删除插件

1、编写插件LogicDeleteInterceptor

@Slf4j@AllArgsConstructor@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})public class LogicDeleteInterceptor implements Interceptor {    @Override    public Object intercept(Invocation invocation) throws Throwable {        StatementHandler statementHandler = PluginUtils.realTarget(invocation.getTarget());        MetaObject metaObject = SystemMetaObject.forObject(statementHandler);        // 判断是不是SELECT操作 不是直接过滤        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");        if (!SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())) {            return invocation.proceed();        }        BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql");        // 执行的SQL语句        String originalSql = boundSql.getSql();        // SQL语句的参数        Object parameterObject = boundSql.getParameterObject();        String finalSql = this.handleSql(originalSql);//        System.err.println("逻辑删除处理过后的SQL: 
" + finalSql);        metaObject.setValue("delegate.boundSql.sql", finalSql);        return invocation.proceed();    }    /**     * 改写SQL     * {@link com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor}     *     * @param originalSql 执行的SQL语句     * @return 处理后的SQL     * @author zhengqingya     * @date 2022/1/13 10:43     */    private String handleSql(String originalSql) throws JSQLParserException {        CCJSqlParserManager parserManager = new CCJSqlParserManager();        Select select = (Select) parserManager.parse(new StringReader(originalSql));        SelectBody selectBody = select.getSelectBody();        if (selectBody instanceof PlainSelect) {            this.setWhere((PlainSelect) selectBody);        } else if (selectBody instanceof SetOperationList) {            SetOperationList setOperationList = (SetOperationList) selectBody;            List selectBodyList = setOperationList.getSelects();            selectBodyList.forEach(s -> this.setWhere((PlainSelect) s));        }        return select.toString();    }    /**     * 设置 where 条件  --  使用CCJSqlParser将原SQL进行解析并改写     * @param plainSelect 查询对象     */    @SneakyThrows(Exception.class)    protected void setWhere(PlainSelect plainSelect) {        Table fromItem = (Table) plainSelect.getFromItem();        // 有别名用别名,无别名用表名,防止字段冲突报错        Alias fromItemAlias = fromItem.getAlias();        String originalTableName = fromItem.getName();        String mainTableName = fromItemAlias == null ? originalTableName : fromItemAlias.getName();        // 判断是否需要逻辑删除,如果不需要直接过滤        if (!MybatisPlusConfig.LOGIC_DELETE_TABLE.contains(originalTableName)) {            return;        }        // 构建子查询 -- 逻辑删除        String dataSql = mainTableName + ".is_deleted = 0";        if (plainSelect.getWhere() == null) {            plainSelect.setWhere(CCJSqlParserUtil.parseCondExpression(dataSql));        } else {            plainSelect.setWhere(new AndExpression(plainSelect.getWhere(), CCJSqlParserUtil.parseCondExpression(dataSql)));        }    }    /**     * 生成拦截对象的代理     * @param target 目标对象     * @return 代理对象     */    @Override    public Object plugin(Object target) {        if (target instanceof StatementHandler) {            return Plugin.wrap(target, this);        }        return target;    }    /**     * mybatis配置的属性     * @param properties mybatis配置的属性     */    @Override    public void setProperties(Properties properties) {}}

2、配置需要逻辑删除的表

public static Set LOGIC_DELETE_TABLE = new HashSet<>();static {    LOGIC_DELETE_TABLE.add("t_demo");}

3、启用插件

@Bean@ConditionalOnMissingBeanpublic LogicDeleteInterceptor logicDeleteInterceptor() {    return new LogicDeleteInterceptor();}

4、测试

可以看见已经自动加上了is_deleted = 0

在这里插入图片描述

三、本文案例demo源码

https://gitee.com/zhengqingya/small-tools


今日分享语句: 坚定自己想要的。

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章