Mybatis的拦截器学习

简介: 可以创建一个拦截器来拦截 MyBatis 在执行 SQL 语句前后的一些操作,例如修改 SQL 语句、记录 SQL 执行时间等。

当你在使用 MyBatis 框架时,你可以创建一个拦截器来拦截 MyBatis 在执行 SQL 语句前后的一些操作,例如修改 SQL 语句、记录 SQL 执行时间等。在 MyBatis 中,拦截器使用注解 @Intercepts 来标记,而 @Signature 注解则用来标记要拦截的方法。

@Signature 注解中有三个属性:

  1. type:指定要拦截的接口或类,例如 Executor.class,StatementHandler.class 等;
  2. method:指定要拦截的方法名,例如 update、query 等;
  3. args:指定要拦截的方法的参数类型数组,例如 {MappedStatement.class, Object.class},表示要拦截的方法有两个参数,第一个参数的类型是 MappedStatement,第二个参数的类型是 Object。

当你使用了 @Signature 注解后,你就可以将拦截器应用到 MyBatis 的 SQL 执行过程中。在这个过程中,如果执行的方法名、参数类型和数量等与 @Signature 中定义的一致,那么拦截器就会被调用。

下面是一个使用 @Intercepts@Signature 注解的例子:

@Intercepts({
  @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
})
public class MyInterceptor implements Interceptor {
  @Override
  public Object intercept(Invocation invocation) throws Throwable {
    // 在执行 SQL 语句之前,可以修改 SQL 语句或者记录 SQL 执行时间等操作
    Object result = invocation.proceed();
    // 在执行 SQL 语句之后,可以对返回结果进行处理,例如加密数据等操作
    return result;
  }
}

在这个例子中,我们创建了一个拦截器 MyInterceptor,并使用 @Intercepts 注解标记。我们将要拦截的接口类型指定为 Executor.class,要拦截的方法名为 update,参数类型数组为 {MappedStatement.class, Object.class}。

这个拦截器会在执行 Executor 接口中的 update 方法之前和之后被调用,并可以在方法执行前后做一些额外的操作。

除了这个例子,MyBatis 的官方文档中也提供了其他的 @Signature 注解的使用例子,你可以查看这个链接:https://mybatis.org/mybatis-3/zh/configuration.html#plugins

在 MyBatis 中,MappedStatement 类型的参数代表了执行的 SQL 语句,它包含了 SQL 语句的 ID、参数类型、返回类型、SQL 语句字符串等信息。MappedStatement 参数可以通过 Invocation 对象的 getArgs() 方法获取到。

在上面的例子中,我们使用 @Signature 注解指定了拦截器要拦截的方法是 Executor.update(MappedStatement ms, Object parameter)。其中,MappedStatement 类型的参数就是用来传递 SQL 语句信息的。

至于 Object 类型的参数,则是传递给 SQL 语句的参数对象,它可以是任何类型的 Java 对象。在执行 SQL 语句时,MyBatis 会根据 MappedStatement 中定义的参数类型来将 Object 类型的参数转换为对应的 SQL 参数。

总之,MappedStatement 类型的参数和 Object 类型的参数在执行 SQL 语句时都是必须的,它们分别代表了 SQL 语句信息和 SQL 参数。而在拦截器中,我们可以通过 Invocation 对象获取到这两个参数,并对它们进行处理。

MappedStatement 对象通常是 MyBatis 内部自动生成的,包含了 SQL 语句的 ID、参数类型、返回类型、SQL 语句字符串等信息。这个对象会在执行 SQL 语句时自动传入,我们不需要手动传入。

下面是 Executor 接口中 update 方法的源码:

javaCopy code
int update(MappedStatement ms, Object parameter) throws SQLException;

可以看到,在执行 update 方法时,需要传入 MappedStatementObject 类型的参数。这些参数是由 MyBatis 内部调用时传入的。

在 MyBatis 的执行过程中,MappedStatement 对象是在 Configuration 类的 buildAllMappedStatements() 方法中生成的,而参数对象 parameter 则是在执行 SQL 语句时通过 BoundSql 对象与 MappedStatement 相关联生成的。

Mybatis源码学习推荐

  1. MyBatis 官方文档:官方文档中详细介绍了 MyBatis 的各个模块和功能,包括使用、配置、插件等方面,是入门和进阶的必备参考资料。
  2. MyBatis 源代码:MyBatis 是开源项目,源代码可以在官方 GitHub 上找到,可以通过阅读源代码深入了解 MyBatis 的实现原理。
  3. MyBatis 揭秘:这是一本 MyBatis 实现原理的书籍,作者是 MyBatis 的核心开发者之一,详细讲解了 MyBatis 的设计和实现,包括 SQL 解析、映射、缓存、事务等方面。
  4. 《深入浅出MyBatis技术原理与实战》:这是一本非常适合入门的 MyBatis 书籍,讲解了 MyBatis 的基本使用和实现原理,并提供了实例演示,非常适合初学者入门。

@Signature 注解中的 args 数组可以指定被拦截方法的参数类型,可以放任意类型,例如:int.classString.class 等。拦截器会根据指定的参数类型匹配方法的参数类型,只有匹配成功才会拦截该方法。

在 MyBatis 中,@Signature 注解中常用的参数类型除了 MappedStatementObject 之外,还有:

  1. ResultHandler.class:结果处理器,用于处理查询结果,通常在查询大量数据时使用。
  2. RowBounds.class:行分页限制器,用于控制查询的结果数量和偏移量,通常用于分页查询。
  3. CacheKey.classCacheValue.class:用于缓存数据的键和值类型。

除此之外,还可以根据需要自定义参数类型,例如:

@Intercepts({
    @Signature(type = Executor.class, method = "query", args = {
        MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class
    })
})

这里指定了被拦截的方法为 query,参数类型包括 MappedStatement.classObject.classRowBounds.classResultHandler.class,即查询方法的参数类型。

在 MyBatis 中,Interceptor 接口的 intercept 方法中的 Invocation 参数表示被拦截的方法调用,其中的 getArgs 方法返回了被拦截方法的参数列表,是一个数组。

因为在 @Signature 注解中我们指定了被拦截方法的参数类型为 {MappedStatement.class, Object.class},所以 getArgs()[0] 表示的是被拦截方法的第一个参数 MappedStatementgetArgs()[1] 表示的是被拦截方法的第二个参数 Object

所以,invocation.getArgs()[1] 表示的是被拦截方法的第二个参数,即传入到 SQL 语句中的实际参数。在拦截器中,我们可以通过修改这个参数来改变执行 SQL 语句的行为,或者在执行 SQL 语句前后执行一些其他逻辑。

目录
相关文章
|
5天前
|
SQL 监控 Java
mybatis拦截器实现
mybatis拦截器实现
9 0
|
15天前
|
SQL Java 数据库连接
【Mybatis】深入学习MyBatis:概述、主要特性以及配置与映射
【Mybatis】深入学习MyBatis:概述、主要特性以及配置与映射
【Mybatis】深入学习MyBatis:概述、主要特性以及配置与映射
|
2月前
|
SQL XML Java
学习Mybatis相关知识
一、什么是Mybatis? 1、Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。开发人员直接编写原生态sql,即可严格控制sql执行性能、且灵活度高。
13 0
|
2月前
|
XML Java 数据库连接
Mybatis-Plus学习小项目及详细教程
Mybatis-Plus学习小项目及详细教程
|
2月前
|
SQL Java 数据库连接
Mybatis拦截器实现带参数SQL语句打印
Mybatis拦截器实现带参数SQL语句打印
|
4月前
|
SQL Java 数据库连接
MyBatis源码篇:mybatis拦截器源码分析
MyBatis源码篇:mybatis拦截器源码分析
|
4月前
|
SQL 缓存 Java
Mybatis学习文章
Mybatis学习文章
|
4月前
|
SQL Java 数据库连接
还在为学MyBatis发愁?史上最全,一篇文章带你学习MyBatis
还在为学MyBatis发愁?史上最全,一篇文章带你学习MyBatis
|
5月前
|
XML SQL Java
今日记录:学习一个Mybatis的技能之choose 和 bind
今日记录:学习一个Mybatis的技能之choose 和 bind
26 1
|
5月前
|
算法 数据库
MYSQL-mybatisplus的主键自增问题与@Tableld@TableField@TableLogic的学习
关于org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.laoyang.Mapper.BookMapper.deleteById问题