前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >0基础学习Mybatis系列数据库操作框架——自定义拦截器

0基础学习Mybatis系列数据库操作框架——自定义拦截器

作者头像
方亮
发布2024-05-24 19:27:52
500
发布2024-05-24 19:27:52
举报
文章被收录于专栏:方亮方亮
大纲

  • 代码
  • 配置
  • 测试
  • 总结
  • 参考资料

一般我们在生产环境中,业务代码是不允许删除数据库中任何一项数据的。只可以通过逻辑删除的形式来表达删除状态,即给表新增一个类似deleted的字段,默认值false表示该项没有被标记为“删除状态”;如果业务代码想删除该条目,则将该条目的deleted设置为true。查询时带上条件deleted=false来查询“存在”的数据。 我们作为代码设计者,可以通过设计Mybatis的拦截器来拦截通过Mybatis执行的Delete操作。 具体做法就是使用插件技术。

代码

我们需要设计一个类继承于org.apache.ibatis.plugin.Interceptor,并覆盖intercept方法。 在intercept中,我们需要找到MappedStatement对象,然后查看其SqlCommandType是不是DELETE。如果是DELETE,则抛出异常,告诉开发人员,不能执行Delete操作。否则交给调用器按正常流程调用。 因为Delete行为会修改表中项目,所以它属于更新行为,于是Intercepts注解中,我们给method传递的是update。

代码语言:javascript
复制
package org.example.interceptor;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;

import java.util.Properties;

@Intercepts(@Signature(
        type = Executor.class,
        method = "update",
        args = {MappedStatement.class, Object.class}
))
public class DeleteInterceptor implements Interceptor {
    private Properties properties;

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        for (Object a : invocation.getArgs()) {
            if (a.getClass() == MappedStatement.class) {
                MappedStatement statement = (MappedStatement) a;
                if (statement.getSqlCommandType() == SqlCommandType.DELETE) {
                    throw new RuntimeException("Delete operation is not allowed");
                }
            }
        }
        return invocation.proceed();
    }

    @Override
    public void setProperties(Properties properties) {
        this.properties = properties;
    }
}

配置

我们只需要在mybatis-config.xml下新增plugins配置即可。

代码语言:javascript
复制
    <plugins>
        <plugin interceptor="org.example.interceptor.DeleteInterceptor">
        </plugin>
    </plugins>

测试

下面代码中两个例子都是试图执行Delete操作,都会抛出异常。

代码语言:javascript
复制
package org.example;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.example.mapper.AllTypeMapper;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.InputStream;

public class InterceptorTest {
    private static SqlSessionFactory sqlSF;

    @BeforeAll
    static void CreateSessionFactory() throws IOException {
        InputStream in = Resources.getResourceAsStream("mybatis/config/mybatis-config-interceptor.xml");
        sqlSF = new SqlSessionFactoryBuilder().build(in);
    }

    @Test
    void testDeleteElem() {
        try (SqlSession s = sqlSF.openSession(true)) {
            AllTypeMapper all_type_mapper = s.getMapper(AllTypeMapper.class);
            long count = all_type_mapper.deleteElem("info_int", "<",105);
            System.out.println(count);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    @Test
    void testDeleteElemWhereInfoIntLessThen() {
        try (SqlSession s = sqlSF.openSession(true)) {
            AllTypeMapper all_type_mapper = s.getMapper(AllTypeMapper.class);
            long count = all_type_mapper.deleteElemWhereInfoIntLessThen(103);
            System.out.println(count);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

总结

Mybatis的拦截器除了可以拦截Delete操作,还可以拦截很多Mybatis框架内部其他行为。具体见:

  • Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
  • ParameterHandler (getParameterObject, setParameters)
  • ResultSetHandler (handleResultSets, handleOutputParameters)
  • StatementHandler (prepare, parameterize, batch, update, query)

代码样例见:https://github.com/f304646673/mybatis_demo.git

参考资料

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 大纲
  • 代码
  • 配置
  • 测试
  • 总结
  • 参考资料
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档