MyBatis整体架构包含哪些层呢?这些层次是如何设计的呢?
1. MyBatis架构概览
MyBatis框架整体设计如下:
MyBatis整体架构包含哪些层呢?这些层次是如何设计的呢?
MyBatis框架整体设计如下:
减少资源的浪费,MyBatis会在表示会话的SqlSession对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,当下次查询的时候,如果判断先前有个完全一样的查询,会直接从缓存中直接将结果取出,返回给用户,不需要再进行一次数据库查询了。
每当我们使用MyBatis开启一次和数据库的会话,MyBatis会创建出一个SqlSession对象表示一次数据库会话。
在对数据库的一次会话中,我们有可能会反复地执行完全相同的查询语句,如果不采取一些措施的话,每一次查询都会查询一次数据库,而我们在极短的时间内做了完全相同的查询,那么它们的结果极有可能完全相同,由于查询一次数据库的代价很大,这有可能造成很大的资源浪费。
MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能。
MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能。
【本文为低优先级】通过上文我们知道配置是如何加载并初始化的,那MyBatis提供了哪些配置呢?通过MyBatis官网文档我们一探究竟。PS:对于清单型的,只需要大致浏览且在使用时能快速查找即可,所以是低优先级的。
MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。通过上一篇的初始化过程,我们就能看出,在mybatis的配置文件中:
【本文为中优先级】通过上文我们知道MyBatis初始化过程中会解析配置,那具体是如何解析的呢?
上文配置解析中,我们看到如下的主体方法:
public Configuration parse() {
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
//源码中没有这一句,只有 parseConfiguration(parser.evalNode("/configuration"));
//为了让读者看得更明晰,源码拆分为以下两句
XNode configurationNode = parser.evalNode("/configuration");
parseConfiguration(configurationNode);
return configuration;
}
/**
* 解析 "/configuration"节点下的子节点信息,然后将解析的结果设置到Configuration对象中
*/
private void parseConfiguration(XNode root) {
try {
//1.首先处理properties 节点
propertiesElement(root.evalNode("properties")); //issue #117 read properties first
//2.处理typeAliases
typeAliasesElement(root.evalNode("typeAliases"));
//3.处理插件
pluginElement(root.evalNode("plugins"));
//4.处理objectFactory
objectFactoryElement(root.evalNode("objectFactory"));
//5.objectWrapperFactory
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
//6.settings
settingsElement(root.evalNode("settings"));
//7.处理environments
environmentsElement(root.evalNode("environments")); // read it after objectFactory and objectWrapperFactory issue #631
//8.database
databaseIdProviderElement(root.evalNode("databaseIdProvider"));
//9.typeHandlers
typeHandlerElement(root.evalNode("typeHandlers"));
//10.mappers
mapperElement(root.evalNode("mappers"));
} catch (Exception e) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
}
}
在mapper文件中,以mapper作为根节点,其下面可以配置的元素节点有: select, insert, update, delete, cache, cache-ref, resultMap, sql; 本文将Mapper映射文件配置进行详解。
相信,看到insert, update, delete, 我们就知道其作用了,顾名思义嘛,myabtis 作为持久层框架,必须要对CRUD啊。好啦,咱们就先来看看 insert, update, delete 怎么配置, 能配置哪些元素吧:
本文主要介绍MyBatis数据源和连接池相关的内容。
MyBatis把数据源DataSource分为三种:
相应地,MyBatis内部分别定义了实现了java.sql.DataSource接口的UnpooledDataSource,PooledDataSource类来表示UNPOOLED、POOLED类型的数据源。
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
从上文我们知道MyBatis和数据库的交互有两种方式有Java API和Mapper接口两种,所以MyBatis的初始化必然也有两种;那么MyBatis是如何初始化的呢?
MyBatis的初始化可以有两种方式:
Mybatis的分页功能很弱,它是基于内存的分页(查出所有记录再按偏移量和limit取结果),在大数据量的情况下这样的分页基本上是没有用的。本文基于插件,通过拦截StatementHandler重写sql语句,实现数据库的物理分页。
在前面章节介绍了一次sqlsession的完整执行过程,从中可以知道sql的解析是在StatementHandler里完成的,所以为了重写sql需要拦截StatementHandler。