1 文章开始之前的几句闲话
做任何事情,我们都需要有自己的思考跟想要达到的目标,人的内心就像是湖面的倒影一样,总是飘忽不定且言不由衷,我们要学会让自己的心安静下来,湖面总会归于平静,最终你总还是会看清自己。同样在学习源码的时候,我们也是要有一个主线,带着思考去学习,不能盲目拎不清,什么都想看,但是自己一点儿脑筋都不动肯定不行的,我们每天射箭,可是如果连箭靶子都看不清,那每天拉弓有什么意义?
学而不思则惘,思而不学则殆,与君共勉。
2 Mybatis的使用流程简述
- 创建maven项目,导入Myabtis框架依赖
- 在项目的resources目录下创建mybatis-config.xml全局配置文件
- 在项目的resources创建数据库连接参数配置文件jdbc.properties
- 在mybatis-config.xml文件中的properties标签中引入jdbc.properties配置文件
- 在setting标签中配置设置LogImpl、VfsImpl、二级缓存启停等参数设置
- 在typeAliases标签下的自定义别名设置
- 在environment标签下配置数据库连接信息、数据源及事务管理器相关信息
- 在mappers标签下配置Mapper.xml文件的映射扫描方式及扫描路径
- 其他标签以及以上标签具体的参数配置及配置方法参考https://mybatis.org/mybatis-3/zh/
- 创建实体类
- 创建mapper层的Mapper接口
- 在项目的resources目录下创建mapper层接口包路径相同的目录结构,在该目录下创建mapper对应的*Mapper.xml
- 创建测试类进行mapper层方法测试
3 Mybatis整体结构
3.1 接口层
- 接口层就是其他应用和Mybatis框架交互的入口, 在这个层面最重要得对象就是SqlSession。
- 大家之前肯定学习过JDBC, JDBC的核心也是要创建出这个SqlSession对象用来跟数据库进行交互,Mybatis框架以JDBC为核心进行了封装和扩展。
- SqlSession上定义了非常多的对数据库的操作方法。接口层在接收到调用请求的时候,会调用核心处理层的相应模块来完成具体的数据库操作
3.2 核心处理层
核心处理层主要完成对数据库操作(增删改查)。
核心处理层主要完成以下功能:
- 把接口中传入的参数解析并映射成JDBC类型;
- 解析接口注解(@Select/@SelectProvider/@Insert/@InsertProvider/@Update/@UpdateProvider/@Delete/@DeleteProvider)或者*Mapper.xml文件中的SQL语句,包括输入参数和动态SQL的生成;
- 执行SQL语句;
- 获取默认及自定义拦截器进行处理
- 处理SQL语句执行完毕后的ResultSet结果集,并映射成Java对象。
3.3 基础支撑层
基础支持层主要是一些抽取出来的通用功能(实现复用),用来支撑核心处理层的功能。例如类型转换、接口方法与代理对象的映射关系绑定、缓存、日志、xml解析、反射工具类、IO、事务、数据源等功能。
4 Mybatis的核心流程
我们从业务层面去分析一下Mybatis的核心流程, 这里写一个简单的的查询示例代码
SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder();
try (InputStream ins = Resources.getResourceAsStream("mybatis-config.xml")){
SqlSessionFactory factory = factoryBuilder.build(ins);
SqlSession sqlSession = factory.openSession();
LibBookMapper mapper = sqlSession.getMapper(LibBookMapper.class);
List<LibBook> libBooks &#61; mapper.selectAllBook();
libBooks.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
把上面的代码翻译成执行流程
- 1.先创建了一个SqlSessionFactoryBuilder对象用来获取SqlSessionFactory对象
- 2.读取全局配置文件mybatis-config.xml转成文件流
- 3.调用SqlSessionFactoryBuilder对象构建SqlSessionFactory对象的方法&#xff0c;传入全局配置文件流对象&#xff0c;获取到SqlSessionFactory对象
- 4.通过SqlSessionFactory对象的openSession方法获取到Sqlsession对象
- 5.调用Sqlsession的getMapper(Class calzz)方法获取到接口对应的代理类对象
- 6.执行借口中对应的方法获取到查询结果
绘制成流程图大致如下
5 具体核心流程阅读前的疑问
- 1、全局配置文件mybatis-config.xml文件是怎么解析的&#xff1f;解析出来的对象都保存到了那里&#xff1f;这些对象又是怎么被用到后面的流程中去的&#xff1f;
- 2、*Mapper.xml文件是怎么完成解析的&#xff1f;解析出来的对象保存在哪里&#xff1f;它们又是怎么和JAVA定义的Mapper接口进行映射绑定的&#xff1f;
- 3、如果我们在定义接口方法的时候使用的是&#64;Select/&#64;Insert/&#64;Update/&#64;Delete等注解&#xff0c; 没有使用xml文件的映射方式&#xff0c;注解方式的映射是怎么解析的&#xff1f;
- 4、如果使用的是xml文件映射的方式&#xff0c;这些xml文件是什么时候被载入解析的&#xff0c; 解析完成之后的对象都是怎么存储的&#xff1f;后续的流程中他们又是怎么被使用到的&#xff1f;
- 5、接口方法中的输入参数是JAVA中的数据类型&#xff0c;怎么映射处理成对应数据库中的对应的数据类型的&#xff1f;
- 6、不管是注解还是xml映射文件&#xff0c;SQL语句是怎么解析的&#xff1f;如果SQL语句中包含参数&#xff1f;在SQL语句执行之前&#xff0c;这些占位符中的参数肯定被替换成具体的参数值了&#xff0c;这个
操作是在哪里完成的&#xff1f;涉及到多个参数的占位符替换&#xff0c;每个参数的类型都不相同&#xff0c; 怎么保证参数值替换占位符的时候不会出现错误的&#xff1f; - 7、接口方法中的返回值类型和SQL语句执行完毕返回的ResultSet结果集中的返回值类型是如何实现映射的&#xff1f;在返回ResultSet对象之后&#xff0c;Mybatis是如何把它处理成Java对象的&#xff1f;
- 8、数据库连接对象是什么时候创建的&#xff0c;是一开始就创建了麽&#xff0c;创建数据库连接对象一定要使用连接池麽? 使用连接池和不使用连接池&#xff0c;Myabtis都是如何处理的&#xff1f;
- 9、Mybatis中的事务控制是如何实现的&#xff1f;
- 10、Mybatis的三级缓存的实现原理是怎样的&#xff1f;在具体的代码中是怎么体现的&#xff1f;
- 11、Mybatis插件的实现原理&#xff0c;如何自定义插件?自定义插件如何在mybatis中使用并生效&#xff1f;
- 12、源码肯定会使用设计模式&#xff0c; Mybatis框架中都是用了哪些设计模式&#xff1f; 都体现在代码中的哪些地方&#xff1f;
- 13、Spring框架是如何整体Mybatis的&#xff1f;实现原理是什么&#xff1f;
后面的文章&#xff0c; 我会一点一点儿的说明我在源码中找到的关于以上问题的答案的&#xff0c;如果对我的文章感兴趣&#xff0c;请多关注&#xff0c;如果阐述有问题&#xff0c; 请多指正~