MyBatis拦截器的执行顺序引发的MyBatis源码分析

Posted tuhooo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis拦截器的执行顺序引发的MyBatis源码分析相关的知识,希望对你有一定的参考价值。

你猜一下哪个先执行?反正不要按常规来。

1 <plugins>
2     <plugin interceptor="com.Interceptor1"></plugin>
3     <plugin interceptor="com.Interceptor2"></plugin>
4 </plugins>

之前看有的博客分析源码,都没提到这一点。之前我只是用一下而已,这个顺序测试一下其实结论也很容易获得,但是我有一种看源码的屎命感。MyBatis还算人性化提供了拦截器,iBatis里面就没有了,不过也可以实现。这里要探究拦截器的源码就不得不提到MyBatis的源码,也就是执行流程了。这要是摊开说就有点大了,为了写好这篇,我决定今天晚上回去不打dota了,贡献真实够大的了。

MyBatis的作用

名义上来说MyBatis是一个半ORM框架,用了一个半字是因为MyBatis并没有完全起到一个ORM框架的作用(比如Hibernate),还有一半工作是需要我们参与进来——编写SQL语句。MyBatis替我们干的活是啥?帮我们把参数和配置化SQL语句映射成数据库中真正执行的SQL,然后把结果帮我们封装好,并返回回来。好处很容已说明,配置灵活,增强开发人员对SQL语句的控制,减少了冗余的对象封装工作。

官方的说法如下:

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

MyBatis的架构

沿着上面说到的,我们接下来可以看一下MyBatis用了什么架构来完成上面的工作。要注意,talk is cheap,实际上的话还要牵涉很多工作(比如Session,事务等)。在网上看了一些描述MyBatis架构的图,看来一晚上不打dota是不可能了呀。

功能上的架构:

技术分享图片

源码中的结构:

技术分享图片

架构看上去并不复杂,按三层来分的。之前看的很少,如果你是和我一样的小白话可以一起来看下,从头看起吧,接口和配置文件先开始。

最简单的方式开始MyBatis

这里最简单的意思是,我们先抛开Spring,只在一个简单的Maven项目中使用MyBatis,看看它是如何运行的。先起一个简单的Maven项目并加上MyBatis的依赖。

已经做好了但是,额,写起来估计可以新开一篇了。

单独使用MyBatis分析

其实核心代码只有两个,第一个是SessionUtils用于提供Session,第二个是使用Session进行CRUD操作的代码

 1 public class SessionUtils {
 2     private static SqlSessionFactory sessionFactory;
 3     static {
 4         try {
 5             // 使用MyBatis提供的Resources类加载mybatis的配置文件
 6             Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
 7             // 构建sqlSession的工厂
 8             sessionFactory = new SqlSessionFactoryBuilder().build(reader);
 9         } catch (Exception e) {
10             e.printStackTrace();
11         }
12     }
13 
14     /**
15      * 获取SqlSession
16      * @return SqlSession
17      */
18     public static SqlSession getSession() {
19         return sessionFactory.openSession();
20     }
21 }

 

 

 1 @Test
 2 public void testInsert() {
 3     SqlSession session = null;
 4     try {
 5         session = SessionUtils.getSession();
 6         StudentMapper studentMapper = session.getMapper(StudentMapper.class);
 7         Long affectedLines = studentMapper.insert(build());
 8         System.out.println("affectedLines = " + (affectedLines == null ? 0 : affectedLines));
 9         session.commit();
10     } catch (Exception e) {
11         e.printStackTrace();
12         if(session != null) {
13             session.rollback();
14         }
15     } finally {
16         if(session != null) {
17             session.close();
18         }
19     }
20 }

 

观察这两段代码引出了两个核心的类:SqlSessionFactorySession

 

以上是关于MyBatis拦截器的执行顺序引发的MyBatis源码分析的主要内容,如果未能解决你的问题,请参考以下文章

mybatis(3)—自定义拦截器(上)基础使用

自定义mybatis拦截器

Mybatis-Interceptor

mybatis拦截器(上)

Mybatis拦截器

自定义MyBatis拦截器