MyBatis源码分析:Configuration
MyBatis依赖的jar不多,而且代码行数也没多少,其中使用了大量的设计模式,值得好好学习。下图是MyBatis的一张架构图,来自Java框架篇—Mybatis 入门。
Mybatis的功能架构分为三层:
API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。 数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。 基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。MyBatis整个项目的包结构如下:
. └── org └── apache └── ibatis ├── annotations ├── binding ├── builder ├── cache ├── cursor ├── datasource ├── exceptions ├── executor ├── io ├── jdbc ├── logging ├── mapping ├── parsing ├── plugin ├── reflection ├── scripting ├── session ├── transaction └── type
MyBatis的最基础和常用的是Configuration类,它负责保存MyBatis的一些设置参数,它依赖或者相关的包有:
mapping:通过Environment设置应用环境,Environment依赖datasource和transaction包 transaction:事务 logging:设置日志 type:管理type注册器,默认添加了很多常用类的注册器 reflection:反射相关基础类 cache:管理缓存 scripting:运行脚本 plugin:管理插件 execution:获取executionConfiguration类的所有属性都是protected,其中一些属性是final的,主要提供了两个构造方法:
public Configuration(Environment environment) { this(); this.environment = environment; public Configuration() { typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class); typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class); typeAliasRegistry.registerAlias("JNDI", JndiDataSourceFactory.class); typeAliasRegistry.registerAlias("POOLED", PooledDataSourceFactory.class); typeAliasRegistry.registerAlias("UNPOOLED", UnpooledDataSourceFactory.class); typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class); typeAliasRegistry.registerAlias("FIFO", FifoCache.class); typeAliasRegistry.registerAlias("LRU", LruCache.class); typeAliasRegistry.registerAlias("SOFT", SoftCache.class); typeAliasRegistry.registerAlias("WEAK", WeakCache.class); typeAliasRegistry.registerAlias("DB_VENDOR", VendorDatabaseIdProvider.class); typeAliasRegistry.registerAlias("XML", XMLLanguageDriver.class); typeAliasRegistry.registerAlias("RAW", RawLanguageDriver.class); typeAliasRegistry.registerAlias("SLF4J", Slf4jImpl.class); typeAliasRegistry.registerAlias("COMMONS_LOGGING", JakartaCommonsLoggingImpl.class); typeAliasRegistry.registerAlias("LOG4J", Log4jImpl.class); typeAliasRegistry.registerAlias("LOG4J2", Log4j2Impl.class); typeAliasRegistry.registerAlias("JDK_LOGGING", Jdk14LoggingImpl.class); typeAliasRegistry.registerAlias("STDOUT_LOGGING", StdOutImpl.class); typeAliasRegistry.registerAlias("NO_LOGGING", NoLoggingImpl.class); typeAliasRegistry.registerAlias("CGLIB", CglibProxyFactory.class); typeAliasRegistry.registerAlias("JAVASSIST", JavassistProxyFactory.class); languageRegistry.setDefaultDriverClass(XMLLanguageDriver.class); languageRegistry.register(RawLanguageDriver.class);
说明:
第一个构造方法是通过Environment进行初始化,并调用第二个构造方法,Environment封装了数据源和事务,不同Environment下使用的数据源和事务不一样,例如,实际使用中会有生产和测试环境。 第二个构造方法,主要是注册一些别名并设置默认的语言驱动。Configuration内部维护了以下几种注册器:
这些注册器内部都会维护一个或多个map,然后提供注册register的方法,并且他们都是需要实例化才能使用的,而不是单例的。在一个MyBatis应用的整个生命周期中,只会存在一个Configuration实例。
Configuration内部有一些Map类型的属性:
protected final Map String, MappedStatement mappedStatements = new StrictMap MappedStatement ("Mapped Statements collection"); protected final Map String, Cache caches = new StrictMap Cache ("Caches collection"); protected final Map String, ResultMap resultMaps = new StrictMap ResultMap ("Result Maps collection"); protected final Map String, ParameterMap parameterMaps = new StrictMap ParameterMap ("Parameter Maps collection"); protected final Map String, KeyGenerator keyGenerators = new StrictMap KeyGenerator ("Key Generators collection"); protected final Map String, XNode sqlFragments = new StrictMap XNode ("XML fragments parsed from previous mappers");
可以看到,实际上是使用的StrictMap。每一个StrictMap都有一个名称,put和get操作时需要判断key是否为空,如果为空,则抛出异常。
Configuration内部有一些Collection类型的属性:
protected final Collection XMLStatementBuilder incompleteStatements = new LinkedList XMLStatementBuilder protected final Collection CacheRefResolver incompleteCacheRefs = new LinkedList CacheRefResolver protected final Collection ResultMapResolver incompleteResultMaps = new LinkedList ResultMapResolver protected final Collection MethodResolver incompleteMethods = new LinkedList MethodResolver
为什么接口使用的是Collection而不是List?为什么实现类使用的是LinkedList而不是ArrayList?
更多的配置参数说明,见XML 映射配置文件。
Configuration使用的一个例子:
DataSource dataSource = ...; TransactionFactory transactionFactory = new JdbcTransactionFactory(); Environment environment = new Environment("Production", transactionFactory, dataSource); Configuration configuration = new Configuration(environment); configuration.setLazyLoadingEnabled(true); configuration.getTypeAliasRegistry().registerAlias(Blog.class); configuration.addMapper(BlogMapper.class); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
总结:
Configuration类保存着MyBatis的所有配置参数,并以此为入口为其他服务,如缓存、执行器等等,提供了一些接口,这样方便集中管理和维护代码,但似乎又违背了单一原则?所有配置参数都可以通过Configuration来设置,意味着所有的配置都是可替代的,这样就非常灵活了。
MyBatis 学习笔记(八)---源码分析篇--SQL 执行过程详细分析 在面试中我们经常会被到MyBatis中 #{} 占位符与${}占位符的区别。大多数的小伙伴都可以脱口而出#{} 会对值进行转义,防止SQL注入。而${}则会原样输出传入值,不会对传入值做任何处理。本文将通过源码层面分析为啥#{} 可以防止SQL注入。
MyBatis 学习笔记(六)---源码分析篇---映射文件的解析过程(一) 前面几篇我们介绍了MyBatis中配置文件的解析过程。今天我们接着来看看MyBatis的另外一个核心知识点 映射文件的解析。本文将重点介绍 cache 节点和 cache-ref 的解析。
MyBatis 学习笔记(四)---源码分析篇---配置文件的解析过程(二) 接上一篇MyBatis 学习笔记(四)—源码分析篇—配置文件的解析过程(一) 。上一篇我们介绍了properties 和settings配置的解析过程,今天我们接着来看看其他常用属性的解析过程,重点介绍typeAliases,environments等配置的解析。
MyBatis 学习笔记(四)---源码分析篇---配置文件的解析过程(一) 前几篇我们介绍了MyBatis的一些基本特性,对MyBatis有了个初步了解。接下来,我们将着手来分析一下MyBatis的源码,从源码层面复盘MyBatis的执行流程。
mybatis源码分析 mybatis源码分析 mybatis的流程分析 首先mybatis的源码分两种情况: 单独的mybatis 和spring整合的mybatis源码 这两种情况下的源码分析会有点不同,比如如果是分析m
雨客 微博@JavaChen,这里的所有博客文章来自http://blog.javachen.com/。
Java Spring Boot开发实战系列课程【第15讲】:Spring Boot 2.0 API与Spring REST Docs实战 立即下载
相关文章
- 【源码分析】Mybatis使用中,同一个事物里,select查询不出之前insert的数据
- ssm使用全注解实现增删改查案例——mybatis-config.xml
- 深入浅出Mybatis系列(十)---SQL执行流程分析(源码篇)(转)
- mybatis oracle两种方式批量插入数据
- mybatis 环境搭建和基本说明
- Mybatis面试题整理(超详细)
- 深入浅出Mybatis系列(四)---配置详解之typeAliases别名(mybatis源码篇)
- springboot mybatis注解方式批量insert和使用in语句查询
- Atitit mybatisutil 模块测试功能列表 1.1. mybatis读取mapper配置的sql语句 使用xml类库1 1.2. Mybatis替换参数工具类型3 Itfs pn
- Atitit.mybatis的测试 以及spring与mybatis在本项目中的集成配置说明
- atitit.动态加载数据库配置in orm hibernate mybatis
- 【项目实战】MyBatis的基础源码 —— 配置文件加载源码
- 【项目实战】MyBatis的基础源码 —— MapperProxy(Mapper接口的代理类)源码介绍
- Spring+SpringMVC+Mybatis(开发必备技能)04、mybatis自动生成mapper_dao_model(包含工具与视频讲解) 纯绿色版本、配套使用视频,100%运行成功
- MyBatis快速入门——第四章、mybatis动态sql_if_choose_when
- MyBatis 源代码阅读笔记 1 基于XML配置的代码编写 mybatis-config.xml
- [DB][mybatis]MyBatis mapper文件引用变量#{}与${}差异
- MyBatis源码第9章之继承HashMap并重写方法
- Springboot项目如何实现mybatis的流式查询
- 【MyBatis】| MyBatis概述、MyBatis⼊⻔程序
- 使用MyBatis获得包含内嵌对象或对象集合的结果——MyBatis结果集封装(复杂对象,连接查询结果集封装)
- Mybatis源码分析之(六)mybatis拦截器(Interceptor)的实现原理
- Mybatis源码分析之(三)mapper接口底层原理(为什么不用写方法体就能访问到数据库)