MyBatis源码解读2(2.1、核心对象)
二、MyBatis的核心对象
2.1、核心对象
2.1、MappedStatement
MyBatis其实是对JDBC的进一步封装,我们都知道JDBC有几个重要的对象:
- Statement
- Prepared Statement
- Callable Statement
- ResultSet
Statement、Prepared Statement、Callable Statement分别与数据与进行交互,最终执行返回的结果由ResultSet进行封装。而SqlSession是对上述步骤进行进一步的封装。
mybatis-config.xml最终被封装成了Configuration对象。我们点啊看iabatis的Configuration类可以发现,environment标签都封装在了Configuration这个类的Environment属性当中,而mapper.xml文件中的一个一个的标签一般会被封装在MappedStatement这个对象中,这就注定了一个Mybatis应用中会有N个MappedStatement对象。
还有一个我们很常见的二级缓存的配置在Configuration类中也有对应的属性。我们可以发现他的默认值为true,所以这个属性我们写不写都可以,因为是默认开启的。
而我们写别名的<typeAlioases>标签被mybatis封装成的对象是TypeAliasRegistry
对于mapper.xml文件的注册,我们可以封装在<mappers>这个标签里面,而被mybatis封装的对象是loadedResources。
而最重要的是写sql语句的mapper.xml文件,在Configuration对象中也做了汇总进行封装。
那么此时问题来了,我们写在标签里面的sql语句最终会被封装到哪里了呢?因为sql语句是写在标签里面的,每一个标签都被封装成了一个个的MappedStatement对象,所以我们需要在MappedStatement对象里面去找。我们往下翻会发现一个getBoundSql方法。
我们会发现他的返回值是叫一个BoundSql的对象,这个对象其实就是MyBatis对sql语句的封装。我们点进去看看这个对象,他有这么几个属性。我们来挨个分析一下。
- private final String sql:用于封装我们写的sql
- 其他的用于封装各种参数。
2.2、Executor
Executor是MyBatis中处理功能的核心,对应增删改Executor提供了对应的方法来执行这些操作。
我们打开源码可以发现,Executor是一个接口(一般涉及到操作相关的类型,尽量设计成接口),我们点住alt+7可以打开大纲,看看所有的方法。
我们可以看到他主要有两类方法:
- update:对应的是sql中的增删改,只要是对于数据库有改动的操作都统一归为update
- query:对应的是sql中的查询操作。
- commit、rollback、getTransaction:与事务相关的操作,包括提交、回滚等。
- createCacheKey、isCached:与缓存相关的操作。
Executor接口有3个比较重要的实现:
- BatchExecutor:批处理操作,一次链接,执行多条sql。
- ReuseExecutor:复用Statement,只要你的sql一样,用的Statement就是一样的。这个Executor比较少用,因为我们很少执行同样的sql,同类型的sql哪怕参数不同都不叫一样的sql
- SimpleExecutor:最常用的Executor,也是MyBatis默认的Executor。
2.3、StatementHandler
StatementHandler是MyBatis封装的JDBC的Statement,MyBatis访问数据库操作真正的核心。我们来看一下StatementHandler的源码。
可以看到都是一些简单的增删改查操作。
2.4、ParamentHandler
ParamentHandlerd的作用是把处理参数,把MyBatis的参数替换成底层JDBC的参数。
2.5、ResultSetHandler
ResultSetHandler封装的是JDBC的ResultSet。他的作用是对JDBC中查询结果集ResultSet进行封装。
2.6、TypeHandler
用于处理数据库类型与Java类型之间转换的过程。
2.7、总结
作为总结,我们就来简单的跟一下insert的源码。
SqlSession的insert方法。
DefaultSqlSessionSession的insert方法,我们可以发现insert方法调用的其实是update方法。
还是在DefaultSqlSessionSession同一个类中的update方法。
接着走到了Executor的update方法,注意这个Executor是默认的SimpleExecutor