Mybatis源码剖析—第二讲
那我们在讲完了mappedstatement这个类,它的一个核心作用之后呢?那下面我有一个问题想问问各位。作为mappedstatement来讲,它封装的是一个select标签或者insert标签。但是呢,我们需要大家注意的是什么?在我们开发的过程当中啊,这些我们所写的。select标签也好,还有insert标签儿,update标签儿delay的标签也罢,那么除了它标签儿上的这些内容之外。实际上,我们说它还有一个很重要的东西,
这个东西是什么呢?sql语句。哎,不管是insert标签当中的这个insert into的这条sql,还是我们所说的查询当中的这些select的sqk?那你会发现,作为这些标签,里面是不是都有这个SQL的封装啊?那么,作为这个sql的封装?它在mybatis源码当中是以什么形式来体现的呢?那首先我们大家可以确定的是什么呀?就是一切皆对象,什么最终都会被封装成对象的形式,
SQL语句,它一定是string类型的,但是它并没有。仅仅用一个string单独代表这个sql,而是把这个sql怎么着封装在了这个类里。那当然,我们说与sql相关的还有什么?那显然还有它的相关的参数。因为我们知道后续我们在写sql的时候,它一定不是简单的说select from, 它一定会带上相关参数,将这些统一封装成BoundSql类 从属于Mappedstatement, 这个秉承着责任单一,各司其职的面向对象的设计方式
就目前理解而言 : SqlSession封装JDBC,操作MappedStatement,其实并非这样
操作里包含了,查和改,改包括了增,删,改,还有处理缓存,这些操作由Executor实现,为什么设计成接口呢,根据设计原则来说,操作相关的类型都要设计成接口
它的设计也是这样,查看子类快捷键 ctrl + alt + B ,我们回到Executor类,
这个BaseExecute实际上是这个Execute的一个适配器,实现了一些基本功能,这三个才是最核心的
操作类对象 (SqlSession) ---> 门面 ExcutorExcutor 是Mybatis中处理功能的核心1. 增删改update 查query2. 事务操作 提交 回滚3. 缓存相关的操作Excutor接口 (适配器模式) 操作相关都要设计成接口BatchExcutorJDBC中批处理的操作, BatchExcutor ReuseExcutor目的:复用 Statement (需要sql一样)insert into t_user(ID,name)values(1,‘name1’);insert into t_user(ID,name)values(2,‘name2’);SimpleExcutor常用Excutor Mybatis推荐 默认 Configuration protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
为什么需要批处理呢,因为每次connect连接操作系统都会消耗资源
现在我们知道了,executor是完成操作的。但其实真正完成数据库操作的是statementhandler。那为什么不能把这个executor给省略了,直接用statementhandler呢?还是我们所说的。单一职责的问题
executor他做了三件事。第一件事是增删改。也就是与数据库的。操作那除此之外,它是不是还有事物的控制?它是不是还有缓存的操作 所以实际上executor他做的是三件最主要的工作。那后续它之所以在这样的封装的原因是它把其中的第一部分操作。由statementhandler来进行工作。
采用了适配器模式StatmentHandlerStatementHandler是Mybatis封装了JDBC Statement,真正Mybatis进行数据库访问操作的核心功能:增删改差StatementHandler接口SimpleStatementHandlerJDBC 操作 PreparedStatementHandlerCallableStatementHandler ParameterHandler目的:Mybatis参数 ---》 JDBC 相关的参数 @Param ---> #{} --- > ?ResultSetHandler目的:对JDBC中查询结果集 ResultSet 进行封装 TypeHandlerJava程序操作 数据库Java类型 数据库类型String varcharint numberint int excutor和statementhandler都用到了适配器模式
至此,我们总结一下
executor就是SqlSesson的一种实现,一种执行
跳到实现类中
然后executor可以进行对数据库进行操作,对缓存进行处理,对事务进行操作,具体对数据库的操作由statementhandler来做,通过parameterhandler进行参数处理,resultsethandler进行数据库的返回,相关类型由typehandler来进行控制,statementhandler封装了statement,resultsethandler封装了resuletset,至此我们流程就通了
点进去
跳到实现类
进行重载
交给executor进行执行,点击update方法继续往下深入
至此我们这个流程算是完成了,和我们的结论一一印证了
我们为什么说第一种是代理设计模式呢,因为 UserDAO userDAO = sqlSession.getMapper(UserDAO.class);
我们并没有创建接口的实现类,但userDAO的确是一个子类,让我们瞧瞧
这个动态代理如何实现的呢,我们下一节来讲解