加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长百科 > 正文

简朴相识mybatis拦截器实现道理及实例

发布时间:2020-10-31 19:09:38 所属栏目:站长百科 来源:网络整理
导读:这篇文章首要先容了简朴相识mybatis拦截器实现道理及实例,文中通过示例代码先容的很是具体,对各人的进修可能事变具有必然的参考进修代价,必要的伴侣可以参考下
副问题[/!--empirenews.page--]

  短视频,自媒体,达人种草一站处事

这篇文章首要先容了简朴相识mybatis拦截器实现道理及实例,文中通过示例代码先容的很是具体,对各人的进修可能事变具有必然的参考进修代价,必要的伴侣可以参考下

例行老例,先看些根基观念:

1 拦截器的浸染就是我们可以拦截某些要领的挪用,在方针要领前后加上我们本身逻辑

2 Mybatis拦截器计划的一个初志是为了供用户在某些时辰可以实现本身的逻辑而不必去动Mybatis固有的逻辑。

自界说拦截器

* mybatis 自界说拦截器

* 三步调:

* 1 实现 {@link Interceptor} 接口

* 2 添加拦截注解 {@link Intercepts}

* 3 设置文件中添加拦截器

* 1 实现 {@link Interceptor} 接口

* 详细浸染可以看下面代码每个要领的注释

* 2 添加拦截注解 {@link Intercepts}

* mybatis 拦截器默承认拦截的范例只有四种,即四种接口范例 Executor、StatementHandler、ParameterHandler 和 ResultSetHandler

* 对付我们的自界说拦截器必需行使 mybatis 提供的注解来指明我们要拦截的是四类中的哪一个类接口

* 详细法则如下:

* a:Intercepts 拦截器: 标识我的类是一个拦截器

* b:Signature 签名: 则是指明我们的拦截器必要拦截哪一个接口的哪一个要领

* type 对应四类接口中的某一个,好比是 Executor

* method 对应接口中的哪类要领,好比 Executor 的 update 要领

* args 对应接口中的哪一个要领,好比 Executor 中 query 由于重载缘故起因,要领有多个,args 就是指明参数范例,从而确定是哪一个要领

* 3 设置文件中添加拦截器

* 拦截器着实就是一个 plugin,在 mybatis 焦点设置文件中我们必要设置我们的 plugin :

* plugin interceptor="liu.york.mybatis.study.plugin.MyInterceptor"

* property value="LiuYork"/

* property value="123456"/

* /plugin

* 拦截器次序

* 1 差异拦截器次序:

* Executor - ParameterHandler - StatementHandler - ResultSetHandler

* 2 对付统一个范例的拦截器的差异工具拦截次序:

* 在 mybatis 焦点设置文件按照设置的位置,拦截次序是 从上往下

@Intercepts({

@Signature(method = "update", type = Executor.class, args = {MappedStatement.class, Object.class}),

@Signature(method = "query", type = StatementHandler.class, args = {Statement.class, ResultHandler.class})

public class MyInterceptor implements Interceptor {

* 这个要领很好领略

* 浸染只有一个:我们不是拦截要领吗,拦截之后我们要做什么工作呢?

* 这个要领内里就是我们要做的工作

* 表明这个要领前,我们必然要领略要领参数 {@link Invocation} 是个什么鬼?

* 1 我们知道,mybatis拦截器默认只能拦胶?种范例 Executor、StatementHandler、ParameterHandler 和 ResultSetHandler

* 2 不管是哪种署理,署理的方针工具就是我们要拦截工具,举例声名:

* 好比我们要拦截 {@link Executor#update(MappedStatement ms, Object parameter)} 要领,

* 那么 Invocation 就是这个工具,Invocation 内里有三个参数 target method args

* target 就是 Executor

* method 就是 update

* args 就是 MappedStatement ms, Object parameter

* 假如照旧不能领略,我再举一个需求案例:看下面要领代码内里的需求

* 该要领在运行时挪用

@Override

public Object intercept(Invocation invocation) throws Throwable {

* 需求:我们必要对全部更新操纵前打印查询语句的 sql 日记

* 那我就可以让我们的自界说拦截器 MyInterceptor 拦截 Executor 的 update 要领,在 update 执行前打印sql日记

* 好比我们拦截点是 Executor 的 update 要领 : int update(MappedStatement ms, Object parameter)

* 那当我们日记打印乐成之后,我们是不是还必要挪用这个query要领呢,怎样如挪用呢?

* 以是就呈现了 Invocation 工具,它这个时辰着实就是一个 Executor,并且 method 对应的就是 query 要领,我们

* 想要挪用这个要领,只必要执行 invocation.proceed()

/* 由于我拦截的就是Executor,以是我可以强转为 Executor,默认环境下,这个Executor 是个 SimpleExecutor */

Executor executor = (Executor)invocation.getTarget();

* Executor 的 update 要领内里有一个参数 MappedStatement,它是包括了 sql 语句的,以是我获取这个工具

* 以下是伪代码,思绪:

* 1 通过反射从 Executor 工具中获取 MappedStatement 工具

* 2 从 MappedStatement 工具中获取 SqlSource 工具

* 3 然后从 SqlSource 工具中获取获取 BoundSql 工具

* 4 最后通过 BoundSql#getSql 要领获取 sql

MappedStatement mappedStatement = ReflectUtil.getMethodField(executor, MappedStatement.class);

SqlSource sqlSource = ReflectUtil.getField(mappedStatement, SqlSource.class);

BoundSql boundSql = sqlSource.getBoundSql(args);

String sql = boundSql.getSql();

logger.info(sql);

* 此刻日记已经打印,必要挪用方针工具的要领完成 update 操纵

* 我们直接挪用 invocation.proceed() 要领

* 进入源码着实就是一个常见的反射挪用 method.invoke(target, args)

* target 对应 Executor工具

* method 对应 Executor的update要领

* args 对应 Executor的update要领的参数

return invocation.proceed();

* 这个要领也很好领略

* 浸染就只有一个:那就是Mybatis在建设拦截器署理时辰会判定一次,当前这个类 MyInterceptor 到底需不必要天生一个署理举办拦截,

* 假如必要拦截,就天生一个署理工具,这个署理就是一个 {@link Plugin},它实现了jdk的动态署理接口 {@link InvocationHandler},

* 假如不必要署理,则直接返回方针工具自己

* Mybatis为什么会判定一次是否必要署理呢?

* 默认环境下,Mybatis只能拦胶?种范例的接口:Executor、StatementHandler、ParameterHandler 和 ResultSetHandler

* 通过 {@link Intercepts} 和 {@link Signature} 两个注解

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读