Mybatis的运行分为两部分,第一部分是读取配置文件缓存到Coufiguration对象,用以创建SqlSessionFactory,第二部分是SqlSession的执行过程。
Mybatis实现的基本原理是利用:动态代理和反射机制。动态代理中用到JDK动态代理和CGLIB代理。这两者的区别是,JDK动态代理是接口的,CGLIB代理是对于类的。Mybatis中这两种代理都用到过,Mapper中用到的是JDK动态代理,在延迟加载的时候用到CGLIB代理。
(1) 构建SqlSessionFactory过程
SqlSessionFactory是Mybatis的核心类,主要功能时提供创建Mybatis的核心接口SqlSession,我们需要创建SqlSessionFactory,为此我们提供配置文件和相关参数。通过SqlSessionFactoryBuilder去构建。
首先通过org.apache.ibatis.builder.xml.XMLConfigBuilder解析配置的XML文件,读取配置参数,并将读取的数据存入这个org.apache.ibatis.session.Configuration类中。其次使用Configuration对象去创建SqlSessionFactory。
(2) 构建Configuration
Configuration的作用;
1 读取配置文件,包括基础配置的XML文件和映射器的XML文件
2 初始化基础配置,比如Mybatis的别名等,一些重要的类对象,例如,插件、映射器、ObjectFactory和typeHandler对象。
3 提供单例,为后续创建SqlSessionFactory服务并提供配置的参数。
4 执行一些重要的对象方法,初始化配置信息。
(3) 映射器的内部组成
一般而言映射器有三部分组成,MappedStatement、SqlSource和BoundSql。
MappedStatement:它保存了一个映射器的节点(select|delete|update)。包括许多我们配置的SQL、SQL的id、缓存信息、resultMap、paramterType、resultType、languageDriver等重要配置信息。
SqlSource:提供BoundSql的地方,它是MappedStatement的一个属性。是一个接口,主要作用是根据参数和其它的规则组装SQL。
BoundSql:建立SQL和参数的地方。常用用用三个参数:SQL,parameterObject、parameterMappings。
(4) 构建SqlSessionFactory
sqlsessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
(5)SqlSession运行过程
SqlSession是一个接口,使用它并不复杂。我们构建SqlSessionFactory就可以轻松容易地拿到Sqlseesion了。
1) 映射器的动态代理
Mapper映射是通过动态代理来实现的。映射器的xml命名空间对应的便是这个接口的全路径,那么它根据全路径和方法名便能够绑定起来,通过动态代理技术,让这个接口跑起来。
2) SqlSession下的四大对象
映射器其实就是一个动态代理对象,进入到了MapperMethod的execute方法。它经过简单的判断就进入了SqlSession的删除、更新、插入和选择等方法。
Mapper的执行其实就是通过Executor、StatementHandler、ParameterHandler和ResultHandler来完成数据操作和结果的返回。
Executor:执行器,由它来调度StatementHandler、Parameterhandler、ResultHandler等来执行对应的SQL。
StatementHandler:使用数据的Statement执行操作,它是四大对象的核心,起到承上启下的作用。
ParameterHandler:用于SQL对参数的处理。
ResultHandler:进行最后数据集(ResultSet)的封装返回处理。
1) 执行器(Executor):它是一个真正执行Java和数据交互的地方。在Mybatis中有三种执行器。SIMPLE(简单执行器,这是默认的)、REUSE(重用预处理语句)和Batch(执行重用语句和批量更新,它是针对批量专用的执行器)。
2) 数据库会话器(StatementHandler):专门来处理数据库会话的。
3) 参数处理器(ParameterHandler):对预编译语句进行参数处理。
4) 结果处理器(ResultSetHandler):组装结果集的返回。
(5) 总结
SqlSession是通过Executor创建StatementHandler来运行的,而StatementHandler要经过下面的三步。Prepared预编译SQL、parametersize设置参数和query/update执行SQL。
其中parametersize是调用parameterHandler的方法去设置的,而参数是根据类型处理器typeHandler去处理。query/update方法通过resultHandler进行处理结果的封装,如果是update语句,它就返回整数,否则它就通过typeHandler处理结果类型,然后用ObjectFactory提供的规则组装对象,返回给调用者,这就是SqlSession执行的过程。