Mybatis-03-Mybatis的执行流程和使用注解开发


Mybatis版本3.5.2

		<dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.2</version>
        </dependency>

看源码不要着急,一步一个脚印,多想想,多看看~

我们为什么要使用接口来开发?

答案只有两个字:解耦

1、Mybatis的执行流程

在这里插入图片描述
通过阅读Mybatis源码我们可以知道,我们在执行一个Mybatis程序的时候,

  • 首先会通过Resources类来获取mybatis核心配置文件;
  • 然后再去实例化SqlSessionFactory构造器
  • 取得构造器之后,再通过XMLConfigBuilder去解析mybatis配置文件,取得配置信息
  • 再实例化SqlSessionFactory

1.1 首先会通过Resources类来加载mybatis核心配置文件

在这里插入图片描述

1.2 通过SqlSessionFactoryBuilder的build方法来创建SqlSessionFactory

进入源码

1.2.1 进入build方法

在这里插入图片描述
我们可以发现,它又去调用了另一个build方法,点过去看看

点过去之后我们发现,它通过inputStream这些东西取得了一个XMLConfigBuilder对象 在这里插入图片描述

1.2.1.1 我们通过源码可以发现这个SqlSesionFactoryBuilder对象又调用了一个parse方法

在这里插入图片描述

1.2.1.2 我们进入parse方法看看做了什么

在这里插入图片描述
parse方法去解析了configuration节点下的子节点,解析完成之后将解析的结果放到Configuration对象中

1.2.1.3 我们返回使用Configuration对象的方法,发现它将这个Configuration又交给了一个build方法

在这里插入图片描述

1.2.1.4 我们进入到这个build方法之后发现,它通过这个Configuration对象创建了一个DefaultSqlSessionFactory对象

在这里插入图片描述

(DefaultSqlSessionFactory是SqlSessionFactory的实现类,为什么不直接new一个DefaultSqlSessionFactory对象出来?
因为我们new的话需要一个Configuration对象,但是这个对象我们直接没有,所以就直接把xml字节流给SqlSessionFactoryBuilder,我们的DefaultSqlSessionFactory就不用去找Configuration怎么来;这是一种设计模式)

1.2.2 现在我们已经有DefaultSqlSessionFactory对象了,就可以去openSession了

1.2.2.1 进入DefaultSqlSessionFactory类中我们可以发现,这个openSession方法又去调用了一个openSessionFromDataSource方法

在这里插入图片描述

1.2.2.2 进入这个方法后我们可以看到
  • 通过我们的Configuration对象得到环境变量
  • 通过环境变量去实例化了一个事务工厂TransactionFactory
  • 事务工厂通过这些参数帮我们产生了transaction进行事务管理
  • 又通过transaction对象创建了Executor执行器(这个Executor就相当于JDBC中的Statement用来发送执行SQL语句)
    在这里插入图片描述

1.3 现在我们就可以得到SqlSession了,有了SqlSession我们就可以去执行sql语句了

1.3.1 我们进入sqlSession.getMapper();方法去看一下怎么执行的

1.先找到它的实现类
在这里插入图片描述
2.我们进入之后可以发现它的实现类又调用了一个getMapper方法
在这里插入图片描述
3.进入这个getMapper方法之后我们可以发现他又是通过mapperRegistry去getMapper的
在这里插入图片描述
4.进入mapperRegistry的getMapper
在这里插入图片描述
我们可以发现它通过一个HashMap来存储配置文件中的mappers标签的每个mapper接口
5.进入newInstance方法之后发现它是通过JDK动态代理帮Mapper接口生成代理类
在这里插入图片描述
5.代理对象的getUserList方法是走的MapperProxy的invoke方法
在这里插入图片描述
6.在invoke方法中又去走execute方法
在这里插入图片描述

进来之后我们可以发现这里先是判断我们执行的sql语句是什么,然后又去调用了一个executeWithResultHandler,我们选select类型

7.executeWithResultHandler又去调用我们DefaultSqlSession中select方法
在这里插入图片描述
在这里插入图片描述
8.这个select又调用了另一个select方法,我们可以发现他是通过executor来执行查询操作的
在这里插入图片描述
9.我们的executor先走二级缓存来查询

关于缓存
在这里插入图片描述
这里它又调用了一个query方法
在这里插入图片描述
10.进入这个query方法之后我们发现,它是判断二级缓存中有没有,没有的话就去一级缓存查
在这里插入图片描述
11.我们进入在一级缓存查询的查询方法发现,如果一级缓存中没有,它才去数据库中查询
在这里插入图片描述
12.从数据库中查出来之后就把它放到一级缓存中去
在这里插入图片描述

13.一级缓存就是一个HashMap
在这里插入图片描述

2、使用注解开发

2.1 开发流程

1.注解在接口上实现

@Select("select * from user")
List<User> getUsers();

2.需要在核心配置文件中绑定接口

<!--绑定接口-->
    <mappers>
        <mapper class="com.hao.dao.UserMapper"/>
    </mappers>

3.测试

    @Test
    public void testGetUsers() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        //底层主要应用反射
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        List<User> userList = mapper.getUsers();

        for (User user : userList) {
            System.out.println(user);
        }

        sqlSession.close();
    }

注解本质:反射机制实现

底层:动态代理

我们使用注解开发可以省去配置xml文件,但是不建议使用注解开发,因为注解开发存在局限性,并且不能处理复杂的场景,或者说是不能处理一对多、多对多、动态sql这些场景,这些场景在后面都会说。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值