Mybatis 基础

2020/01/10

mybatis 作为一个流行的半ORM框架,在业务开发中经常会用到,近期看了框架的源码,熟悉了其基本架构,在此记录一下相关的知识点。具体的源码分析推荐看看这个源码讲解

核心组件

SqlSessionFactory

会话工厂类,可通过 SqlSessionFactoryBuilder 传入配置文件输入流运用建造者设计模式进行创建。首先创建一个 XmlConfigBuilder,然后调用 xmlConfigeBuilder.parse 方法解析<configuration>标签进而创建 Configuration 对象,再将其作为参数调用 build 重载方法创建 DefaultSqlSessionFactory。SqlSessionFactory 负责初始化流程,运用工厂设计模式提供 SqlSession 对象的获取。DefaultSqlSessionFactory 作为默认实现,这个类的实例的生命周期是全局的,它只会在首次调用时生成一个单例。

SqlSession

会话类,用来执行命令、获取映射、管理事务等一系列操作。通过DefaultSqlSessionFactory.openSession方法获取,其中会先获取Executor,然后作为DefaultSqlSession的构造参数初始化sqlSession对象,所以一个会话就有一个执行器与之绑定。SqlSession中定义了一系列模版方法,用于执行一些简单的CRUD操作。也可以通过getMapper获取mapper实例,执行在mapper.xml中自定义的sql语句。还有可能涉及到事务操作,所以还会有commit、rollback、close等方法。

Executor

执行器类,它有两个实现类BaseExecutor和CachingExecutor。CachingExecutor用来处理二级缓存使用的。BaseExecutor是一个抽象类,是Executor的默认实现,实现了大部分接口方法,是模板设计模式的体现。它有三个子类,分别为:SimpleExecutor、ReuseExecutor和BatchExecutor。

  • SimpleExecutor:简单执行器,默认值。
  • ReuseExecutor:内部有一个statementMap,存储statementHandler创建的statement,可以重复使用statement。
  • BatchExecutor:批量执行。

StatementHandler

封装了JDBC Statement操作,子类有BaseStatementHandler和RoutingStatementHandler。BaseStatementHandler中有成员变量ParameterHandler和ResultSetHandler,所以StatementHandler还包括参数的设置和结果集的转换。BaseStatementHandler子类有SimpleStatementHandler、PrepareStatementHandler和CallableStatementHandler。

  • SimpleStatementHandler:简单statement处理器,默认值。
  • PrepareStatementHandler:执行带有参数的statement,需要配合ParameterHandler完成参数的填充。
  • CallableStatementHandler:执行存储过程的statement。

ParameterHandler

负责对用户传递的参数转换成JDBC Statement所需要的参数。DefaultParameterHandler为默认实现。

ResultSetHandler

负责结果集的转化。DefaultResultSetHandler为默认实现。

缓存处理

参考文档

一级缓存

BaseExecutor有成员变量localCache,默认为sqlSession级别,可通过设置localCacheScope为statement或设置flushCache=true来关闭一级缓存。 update、insert、delete都会变成update、执行完成之后也会清空localCache。

二级缓存

CachingExecutor通过cacheKey来查找缓存,这个缓存在mappedStatement里,在服务启动时初始化Configuration时进行加载,所以二级缓存是全应用级别的。 只用设置了useCache=true,有mapper.xml文件中得有<cache><cache-ref>标签。

mapper.xml中SQL语句与mapper接口方法的绑定原理

通过defaultSqlSession.getMapper调用成员变量configuration的getMapper方法,再调用configuration的成员变量mapperRegistry的getMapper方法。MapperRegistry内有一个knownMappers的Map,key为class类型,value为MapperProxyFactory。通过类型查得MapperProxyFactory,调用其newInstance方法创建一个MapperProxy(继承了InvocationHandler)对象,将其作为Proxy.newInstace方法的参数创建代理对象。当代理对象执行方法时,会调用MapperProxy重写的invoke方法,MapperProxy中有一个key为Method,value为MapperMethod的map,映射一下得到mapperMethod。当第一次执行某一个method的时候,对应的mapperMethod为空,就会从configuration中查找对应的mappedStatement,然后解析出SqlCommand和MethodSignature,构建mapperMethod实例,加入map中。从而实现了mapperInterface.method和mapper.xml中的statement的对应关系。再后续就是将具体的逻辑交给executor去执行,通过StatementHandler、ParameterHandler、ResultSetHandler去做转化。

常用配置

|属性|描述说明| |-|-| |cacheEnable|二级缓存| |lazyLoadingEnable|延迟加载 |localCacheScope|本地缓存范围,默认为session,可以设置为statement,这样就保证没次执行完statement就会清除缓存,实现关闭一级缓存的目的。

(转载本站文章请注明作者和出处 wyc1856