mybatis若想实现自定义拦截器,需要实现Interceptor接口,对象首先会执行plugin(Object target)方法,根据类上的@Intercepts注解决定是否拦截。若需要拦截,则调用intercept(Invocation invocation)方法。
1. 准备工作
需要拦截的sql:
需要拦截的Mapper对象:
invocation对象:

invocation对象
可以看到invocation中的args参数,就是@Intercepts中的args参数。
2. mappedStatement对象
1. invocation对象如何获取mappedStatement对象:
一个mappedStatement对象对应Mapper配置文件中的一个select/update/insert/delete节点,主要描述的是一条sql语句。

MappedStatement.png
2. MappedStatement对象详解:
其中真正表示SQL的字段是SqlSource这个对象。
而SqlSource接口很简单,只有一个getBoundsql方法。
sqlSource有很多实现,需要我们重点关注的是StaticSqlSource,RawSqlSource和DynamicSqlSource。而通过上述的实现,便可以将mybatis特有的sql格式转化成可供PrepareStatement直接执行的sql。
mappedStatement —— BoundSql对象:
上述方法主要是对动态标签的解析,获取完全可执行的sql。对#{ }字符解析,将其替换成?,最后均包装成域表达式供PrepareStatement调用。
解析后的sql保存在sql对象中;
请求参数保存在parameterObject对象中;
#{ }key属性以及相对应的参数映射,比如javaType,jdbcType等信息均保存至BoundSql的parameterMapping属性中。供最后的域表达式对象PrepareStatement赋值使用。

BoundSql .png
BoundSql—解析后的sql对象:
BoundSql对象中的sql对象是对动态标签解析后的完全可执行的sql。
BoundSql—ParameterObject对象:
该对象为sql执行的参数。也就是我们传入的参数。因为使用了@param注解,故有两种方式可以获取到value的值。

parameterObject.png
注意:ParameterObject是一个Object对象,上传不同的参数时,该对象的类型不同。
若上传一个参数对象时:为该参数的类型;
若上传多个参数对象时:为ParamMap对象,由于我们使用了@Param注解,故可以使用注解的key,也可以使用param1取出变量。
若上传的为Criteria对象时(如下图):也是为该对象的类型,但是获取对象的方法又不相同。

Criteria对象.png
注意:如果真实传递进来的参数在TypeHandlerRegistry对象中声明的话,则使用真实传递进来的参数作为真实的变量名。
换句话说,我们在Mapper接口里面写delete(Integer id),而在Mapper.xml中定义的变量#{var}可以随便命名,都可以被mybatis正确处理。
BoundSql—ParameterMapping对象:
采用#{var}的形式来引用变量时,其中的变量会在解析Mapper.xml文件中的语句时,就被替换成占位符“?”,同时通过ParameterMapping类记录对应的变量信息。在真正执行对应语句的时候回传递真实的参数。根据parameterMapping信息给ParameterStatement设置参数。

Criteria对象的ParameterMapping对象.png

普通对象的ParameterMapping对象.png
需要注意的是,property参数就是#{var}中的var。
BoundSql—additionalParameters对象
若是使用Criteria对象时的sql,那么在additionalParameters中便有值,我们可以使用:

Criteria对象的additionalParameters参数.png
BoundSql—MetaObject对象
MetaObject类相当于一个工具类,Mybatis在sql参数设置和结果集映射里经常使用到这个对象。

MetaObject.png
MappedStatement——Configuration对象
mybatis会在启动时读取所有的配置文件,然后加载到内存中,Configuration对象就是承载整个配置的类。
Configuration — TypeHandlerRegistry对象
类型处理器注册对象。在构建TypeHandlerRegistry对象的时候,便将类型注册了进去。
类型处理器TypeHandlerRegistry简单点就是用于处理javaType与jdbcType之间的类型转换用的处理器,Mybatis针对诸多Java类型与数据库类型进行了匹配处理。
类型处理器的格式:
本文详细介绍了Mybatis自定义拦截器的实现过程,通过Interceptor接口和@Intercepts注解进行拦截。重点分析了如何从invocation对象获取mappedStatement,理解MappedStatement对象的结构,包括SqlSource、BoundSql、ParameterObject、ParameterMapping和additionalParameters。此外,还探讨了MetaObject和Configuration对象在Mybatis中的作用,特别是TypeHandlerRegistry在处理Java与JDBC类型转换中的角色。
817

被折叠的 条评论
为什么被折叠?



