Mybatis执行流程

一、工作流程:

1.读取 MyBatis 配置文件:mybatis-config.xml 为 MyBatis 的全局配置文件,配置了 MyBatis 的运行环境等信息,例如数据库连接信息。

2.加载映射文件:映射文件即 SQL 映射文件,该文件中配置了操作数据库的 SQL 语句,需要在 MyBatis 配置文件 mybatis-config.xml 中加载。mybatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。

3.构造会话工厂:通过 MyBatis 的环境等配置信息构建会话工厂 SqlSessionFactory。

4.创建会话对象:由会话工厂创建 SqlSession 对象,该对象中包含了执行 SQL 语句的所有方法,是一个既可以发送sql执行并返回结果的,也可以获取mapper的接口

5.Executor 执行器:MyBatis 底层定义了一个 Executor 接口来操作数据库,它将根据 SqlSession 传递的参数动态地生成需要执行的 SQL 语句,同时负责查询缓存的维护。

6.MappedStatement 对象:在 Executor 接口的执行方法中有一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的 SQL 语句的 id、参数等信息。

7.输入参数映射:输入参数类型可以是 Map、List 等集合类型,也可以是基本数据类型和 POJO 类型。输入参数映射过程类似于 JDBC 对 preparedStatement 对象设置参数的过程。

8.输出结果映射:输出结果类型可以是 Map、 List 等集合类型,也可以是基本数据类型和 POJO 类型。输出结果映射过程类似于 JDBC 对结果集的解析过程。


2、Mybatis基本构成

1.SqlSessionFactoryBuilder: SqlSessionFactoryBuilder是利用XML或者Java编码获得资源来构建SqlSessionFactory的,通过它可以构建多个SessionFactory。它的作用就是一个构建器,一旦外面构建了SqlSessionFactory,它的作用就已经完结了,所以它的生命周期只存在于方法的局部,它的作用就是生成一个SqlSessionFactory对象。

2.SqlSessionFactory:SqlSessionFactory的作用是用于创建SqlSession,用于数据库的连接与交互。每次访问数据库都要通过SqlSessionFactory来创建SqlSession,所以SqlSessionFactory的生命周期存在与整个Mybatis的生命周期,且一般一个数据库只对应一个SqlSessionFactory。

3.SqlSession:SqlSession是一个会话,相当于jdbc中的一个connection对象,生命周期为请求数据库处理Sql语句的过程,其采用了外观模式,提供增删查改、提交和关闭会话的API,且是一个现场不安全的对象。

每次创建SqlSession都必须及时关闭会话,否则会占用数据库连接池的活动资源。

SqlSession通过动态代理的方式,将Mapper.XML文件与Mapper接口建立起对应关系,通过Mapper就可以直接获取Mapper.XML文件中Id与接口方法名对应SQL语句,再通过JDBC的方式去执行SQL语句。

4.Executor:SqlSession使用执行器来执行SQL语句其中mybatis中一共有3个执行器:

   SimpleExecutor:每次执行一次update或者select,就会开启一个Statement对象,用完立刻关闭Statement对象。

   ReuseExecutor: 可复用执行器,执行update或者select,会从一个Map<String, Statement>中以sql语句作为key来查找Statement对象,如果存在就使用,不存在就创建,用完后不关闭Statement对象,而是放入Map中。需要维护,防止占用内存过多。

   BatchExecutor:执行update时,会将所有的sql和Statement都添加到一个批处理的集合中,等待统一执行,与JDBC批处理类似。

5.Mapper:Mapper是一个接口,用于Java语句调用SQL。


三、SQL执行流程

1.Java语句中Mapper接口调用。

2.创建一个SqlSession,通过Mapper的ClassName以及Mapper调用的方法获取到对应的SQL语句,同时生成Executor。

3.SQL语句通过Executor中的StatementHandler处理JDBC中SQL语句与Statement的交互。

4.对于SQL与Statement的交互,Executor通过ParameterHandler进行对Statement的SQL语句参数的设置。通过TypeHandler使用3个ArrayList来处理Java类型与SQL数据类型之间的转换(例如String 转 varchar)。

5.Statement执行SQL语句,获取到ResultSet。

6.将ResultSet中SQL数据类型通过TypeHandler转换成Java类型,再通过ResultSetHandler将ResultSet转换成list,即Java语句中调用Mapper接口所获得的数据。

7.释放资源。


四.Mybatis的缓存

mybtis对于sql的查询结果做了缓存的操作,有两种模式,一级缓存和二级缓存,一般默认开启一级缓存,二级缓存需要手动开启。

一级缓存生命周期只在一个SQLSession中作用域也只在一个SQLSession中,对于同一sql语句(同一statementId、同一查询参数、同一分页参数、同一sql脚本、同一环境),如果在一个SQLSession中被执行了多次,那么只有第一次的sql语句会去访问数据库,后续的操作直接在缓存中获取sql查询结果。当SQLSession中发生update操作、commit操作、rollback操作时,Session的关闭或者手动清除时,SQLSession中的所有缓存都会被清空。

二级缓存生命周期为SqlSessionFactory的生命周期作用域也为一个SqlSessionFactory,即同一个SqlSessionFactory中的所有SQLSession可以共享二级缓存中的数据(与一级缓存类似)。当一个SQLSession进行提交时,才会把这个SQLSession中的查询结果缓存存入二级缓存中,如果进行了归滚,那么会将未提交前的查询缓存给丢弃掉,当某个SQLSession进行了Update操作的时候,会将所有二级缓存清空。而SQLSession的关闭和手动清除不能清除二级缓存。对于二级缓存的内存维护,可以指定维护方式和最大缓存个数来进行对二级缓存进行内存维护,维护方式例如:先进先出,最近最少使用等。

但是对于不同的SqlSessionFactory,其二级缓存也不一样,所以可能会产生脏读,所以可以将二级缓存同步至redis来解决这一问题。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容