版权声明:本文为CSDN博主「$码出未来」的原创文章
原文链接:https://blog.csdn.net/yuanshangshenghuo/article/details/119007391
前言本文主要是介绍下java 持久层框架mybatis核心执行原理,首先是介绍下mybatis,就是白话下,唠唠嗑,在就是通过一张mybatis执行流程图来介绍下它的核心执行流程,最后就是对它的几个核心组件进行介绍了。
白话mybatismybatis想必搞java 开发的同学都知道吧,一款java 轻量级持久层框架,它主要的作用就是封装jdbc,简化了我们对jdbc的使用流程,自从用了mybatis,再也看不到connection了,哈哈哈。
它能够通过xml配置(现在有注解)进行参数绑定,参数映射,能够通过标签动态拼接sql,增加灵活性,还能够结果集映射,结果集与java实体类进行高级映射,就不用我们再咔咔咔的处理结果集了,只需要配置一下实体与数据库表字段映射即可,大大节省开发时间,提高开发效率。
其实说到java持久层框架,还有一个很出名的框架Hibernate,这个框架更狠,直接Java实体与数据库表进行关系映射,不用写sql,通过操作java 实体就完事了,Hibernate能够自动帮你拼接sql,执行sql,自动与结果集映射,各种一对一,一对多,多对多表关系通过实体体现出来就ok,然后查询全能带出来。它是一款全自动的orm对象关系映射框架,比起Hibernate 这种全自动orm框架来说mybatis使用稍微繁琐,需要自己写sql ,有些高级的映射也需要自己写,mybatis顶多算个半自动的orm框架,但是mybatis 有个很大的优点就是可控,自己写的sql自己心里有数,你像Hibernate 你如果不懂它底层的执行原理,你怎么知道它那一对多,多对多关系是怎样查出来的,用了几个sql查出来的,但是mybatis就不一样了,你想写一个连表查的sql就写个连表查的sql,不想写连表查,分开写也ok,更加的灵活,可控。
mybatis执行流程介绍上面稍微介绍了一下mybatis,有提到mybatis其实就是封装了jdbc,把jdbc那繁琐的操作帮我们屏蔽掉了,然后就是再做了一些参数封装,参数映射,动态sql,结果集映射的事情,常用的大概就这些了。
下面我们就拿springboot整合的mybatis为例子,看看它是一个怎样的流程。
初始化流程
项目启动,springboot进行自动装配,创建数据源啥的,创建一个mybatis核心组件SqlSessionFactory,创建SqlSessionFactory 的时候要进行配置文件解析,xml mapper文件解析,将我们的一些配置与mapper文件中的内容解析封装到一个Configuration的配置类中。
创建一个SqlSessionTemplate的组件,现在这里知道它也是这个时候创建的就可以了,它里面持有SqlSessionFactory。
扫描package找到@Mapper注解标注的接口,也就是我们那个dao 接口,封装成一个个的FactoryBean,这个东西很重要哈,这个FactoryBean 就是工厂bean,能够创建对应的bean对象,也就是创建我们那个dao接口的对象,具体的创建其实就是生成dao接口的动态代理类了。那什么时候生成dao接口的动态代理呢?其实是在实例化bean的时候spring才会调用FactoryBean的getObject方法来生成动态代理类。
项目初始化的流程我们就介绍完事了,用一张图总结一下
就是3件事
- 创建SqlSessionFactory对象,同时创建congfiguraion对象, 解析配置信息,配置文件,mapper文件到configuration中。
- 创建SqlSessiontTemplate对象,里面持有SqlSessionFactory对象,同时创建了一个SqlSession代理类。
- 扫描mapper接口(也就是dao接口),创建动态代理对象。
执行sql流程就热闹了,各个组件这个时候就出来了。
我们执行sql其实就是执行dao某个方法。
下面我们就拿UserDao里面的一个添加user的方法说吧
当我们service调用UserDao执行addUser的时候。它其实是调用的UserDao的一个动态代理类,就会一个MapperMethod这么一个对象里面的execute方法,就是看看是执行insert方法还是update方法,接着就找到SqlSessionTempplate这个类里面的SqlSessionProxy代理类,然后这个代理类就会找到SqlSessionFactory获取对应的SqlSession,其实就是创建SqlSession,然后SqlSession会找到Executer来执行,它会胡创建一个StatementHandler的类,做一些获取连接,创建statement的事情,然后由ParameterHandler 设置参数,执行sql(发往mysql执行sql语句),返回结果后调用ResultSetHandler处理结果集,做结果集映射啥的(当然insert,update,delete语句的话,就不会使用ResultSetHandler做结果集映射了),这就是粗略的执行流程了。
下面我们把这个流程用图画出来。
其实核心就是红框框起来的那些,Executor创建StatementHandler,然后获取connection数据库连接,创建statement,调用ParameterHandler设置参数,将参数设置到statement中,接着就是发送sql给数据库,执行sql,最后将结果集返回,由ResultSetHandler组件进行结果集的映射。
核心组件介绍上面我们介绍了mybatis初始化流程与执行sql语句的核心流程,流程里面也出现了很多组件,接下来我们用最最通俗的语言介绍下这几个核心组件。
- SqlSessionFactory 这个组件里面维护所有解析好的配置,包括mapper文件,它的核心功能就是创建SqlSession
- SqlSession 一次sql执行生命周期,所谓生命周期就是执行前的操作,执行动作,执行后的操作,具体的执行是由Executor组件*。
- Executor组件的,就是具体干活的,它里面有缓存的一些东西,包括一级缓存,二级缓存,这个后面文章会专门介绍,它创建StatementHandler,调用StatementHandler 方法获取去数据源中获取连接,创建statement,执行sql等。
- StatementHandler 获取连接,创建statement, 调用ParameterHandler 设置参数,执行sql,调用ResultSetHandler组件处理结果集,进行结果集映射等等。
- ParameterHandler 这个就是往statement里面设置参数,我们使用PreparedStatement 防止sql注入的时候,会将sql里面的某些参数值设置成?(问号),接着就会将真正的值设置进去,ParameterHandler 就是干这个事情的。
- ResultSetHandler 就是处理结果集的,将sql执行的结果集进行实体映射啥的。
好了,到这里我们mybatis执行原理就结束了,首先我们介绍了一下mybatis,跟另一款持久层框架Hibernate做了下简单的对比,然后介绍了一下springboot整合mybatis的项目mybatis初始化都干了些啥,执行某个sql(dao方法)的时候,他的一个执行流程,最后我们对执行流程里的一些核心组件做了一下简单的介绍。