Mybatis的源码分析

Mybatis 底层源码分析

  • Mybatis执行流程
    • 流程图
    • 坐标添加
    • 源码分析
      • 1. Configuration.xml
      • 2. Mapper.xml
      • 3. Resources
        • 如何进入Resource
        • 方法解释
      • 4. SqlSessionFactoryBuilder
      • 5. XMLConfigBuilder
      • 6. Configuration
      • 7. DefaultSqlSessionFactory
      • 8. Executor
        • 继承结构
        • BaseExecutor
        • CachingExecutor
      • 9. StatementHandler
      • 10. ResultSetHandler

Mybatis执行流程

流程图

Mybatis的源码分析_第1张图片

mybaits 流程图的上半部分更多的是完成初始化
下半部分主要是实现增删改查操作

坐标添加

通过添加maven坐标 ,进而添加其jar包与源码 ,方便快捷 ; 也可以找到自己的mybatis项目 ,查看相关源码

<dependencies>
		<dependency>
			<groupId>org.mybatisgroupId>
			<artifactId>mybatisartifactId>
			<version>3.2.8version>
		dependency>

源码分析

1. Configuration.xml

该配置文件是MyBatis 的全局配置文件,在这个文件中可以配置诸多项目。常用的内容是别名设置,拦截器设置等。



  <configuration>
       <properties resource="db.properties">
    properties>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            dataSource>
        environment>
    environments>
    <mappers>
        <mapper resource="com/bjsxt/mapper/UserMapper.xml"/>
    mappers>

  configuration>

Properties(属性)
将数据库连接参数单独配置在db.properties 中, 放在类路径下。这样只需要SqlMapConfig.xml 中加载db.properties 的属性值。这样在SqlMapConfig.xml 中就不需要对数据库连接参数硬编码。
将数据库连接参数只配置在db.properties 中,原因:方便对参数进行统一管理

Settings(全局配置参数)
Mybatis 全局配置参数,全局参数将会影响mybatis 的运行行为。比如:开启二级缓存、开启延迟加载

TypeAliases(类型别名)
类型别名是为Java 类型命名一个短的名字。它只和XML 配置有关, 只用来减少类完全限定名的多余部分

Plugins(插件)
MyBatis 允许你在某一点拦截已映射语句执行的调用。默认情况下,MyBatis 允许使用插件来拦截方法调用

Environments(环境集合属性对象)
MyBatis 可以配置多种环境。这会帮助你将SQL 映射应用于多种数据库之中。但是要记得一个很重要的问题:你可以配置多种环境,但每个数据库对应一个SqlSessionFactory。所以,如果你想连接两个数据库,你需要创建两个SqlSessionFactory 实例,每个数据库对应一个。

Environment(环境子属性对象)
ransactionManager(事务管理)
在MyBatis 中有两种事务管理器类型(也就是type=”[JDBC|MANAGED]”)
DataSource(数据源)

Mappers(映射器)
指定映射配置文件位置

<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<package name="org.mybatis.builder"/>

2. Mapper.xml

Mapper.xml 映射文件中定义了操作数据库的sql,每个sql 是一个statement,映射文件是mybatis 的核心

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.bjsxt.mapper.UsersMapper">
	<select id="selectUsers" resultType="com.bjsxt.pojo.User">
		select * from users
	</select>
</mapper>

ResultMap
Mybatis 中可以使用resultMap 完成高级输出结果映射。如果查询出来的列名和定义的pojo 属性名不一致,就可以通过定义一个resultMap 对列名和pojo 属性名之间作一个映射关系

Cache
开启二级缓存

Select
查询语句

Insert
插入语句

Update
更新语句

Delete
删除语句

3. Resources

Resources 工具类会从路径中加载资源,并返回一个输入流对象,对于资源文件的加载
提供了简易的使用方法。

如何进入Resource

在这段代码中 , 选中Resources , 通过鼠标 ctrl+鼠标左键进入 Resources类
InputStream inputStream = Resources.getResourceAsStream(resource);


import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Properties;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import com.bjsxt.mapper.UsersMapper;
import com.bjsxt.pojo.User;

public class Test {

	public static void main(String[] args) throws Exception {
		    String resource = "SqlMapperClient.xml";
		    
		    //通过鼠标 ctrl+鼠标左键进入 Resources类
	        InputStream inputStream = Resources.getResourceAsStream(resource);
	        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
	 
	        SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.REUSE);
	        try {
	        	//sqlSession.selectOne("");
	            UsersMapper userMapper = sqlSession.getMapper(UsersMapper.class);
	            List<User> list = userMapper.selectUsers();
	            for (User user : list) {
	                System.out.printf(user.toString());
	            }
	        } finally {
	            sqlSession.close();
	        }
	}

}

方法解释

加载一个资源有很多方式:
对于简单的只读文本数据,加载为Reader。
对于简单的只读二进制或文本数据,加载为Stream。
对于可读写的二进制或文本文件,加载为File。
对于只读的配置属性文件,加载为Properties。
对于只读的通用资源,加载为URL。

按以上的顺序,Resources 类加载资源的方法如下(全都在本类,如下图的类结构):
Reader getResourceAsReader(String resource);
Stream getResourceAsStream(String resource);
File getResourceAsFile(String resource);
Properties getResourceAsProperties(String resource);
Url getResourceAsUrl(String resource);

Mybatis的源码分析_第2张图片

4. SqlSessionFactoryBuilder

该类是SqlSessionFactory(会话工厂)的构建者类,之前描述的操作其实全是从这里面开启的,首先就是调用XMLConfigBuilder 类的构造器来创建一个XML 配置构建器对象,利用这个构建器对象来调用其解析方法parse()来完成Configuration 对象的创建,之后以这个配置对象为参数调用会话工厂构建者类中的build(Configuration config) 方法来完成SqlSessionFactory(会话工厂)对象的构建。

Mybatis的源码分析_第3张图片

5. XMLConfigBuilder

该类是XML 配置构建者类,是用来通过XML 配置文件来构建Configuration 对象实例,构建的过程就是解析Configuration.xml 配置文件的过程,期间会将从配置文件中获取到的指定标签的值逐个添加到之前创建好的默认Configuration 对象实例中

Mybatis的源码分析_第4张图片

6. Configuration

该对象是Mybatis 的上下文对象,实例化这个类的目的就是为了使用其对象作为项目全局配置对象,这样通过配置文件配置的信息可以保存在这个配置对象中,而这个配置对象在创建好之后是保存在JVM 的Heap 内存中的,方便随时读取。不然每次需要配置信息的时候都要临时从磁盘配置文件中获取,代码复用性差的同时,也不利于开发 (上下文对象 ,保存配置信息)
Mybatis的源码分析_第5张图片

7. DefaultSqlSessionFactory

SqlsessionFactory 该接口是会话工厂, 是用来生产会话的工厂接口,DefaultSqlSessionFactory 是其实现类,是真正生产会话的工厂类,这个类的实例的生命周期是全局的,它只会在首次调用时生成一个实例(单例模式),就一直存在直到服务器关闭。

Mybatis的源码分析_第6张图片

8. Executor

执行器接口,SqlSession 会话是面向程序员的,而内部真正执行数据库操作的却是Executor 执行器,可以将Executor 看作是面向MyBatis 执行环境的,SqlSession 就是门面货,Executor 才是实干家。通过SqlSession 产生的数据库操作,全部是通过调用Executor 执行器来完成的。
Executor 是跟SqlSession 绑定在一起的,每一个SqlSession 都拥有一个新的Executor 对象,由Configuration 创建。

Mybatis的源码分析_第7张图片

继承结构

Mybatis的源码分析_第8张图片
Mybatis的源码分析_第9张图片

BaseExecutor

SimpleExecutor:
每执行一次update 或select,就开启一个Statement 对象,用完立刻关闭Statement 对象。(可以是Statement 或PrepareStatement 对象)

Mybatis的源码分析_第10张图片
ReuseExecutor:
执行update 或select,以sql 作为key 查找Statement 对象,存在就使用,不存在就创建,用完后,不关闭Statement 对象,而是放置于Map内,供
下一次使用。(可以是Statement 或PrepareStatement 对象)
Mybatis的源码分析_第11张图片
BatchExecutor:
执行update(没有select,JDBC 批处理不支持select),将所有sql 都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象,每个Statement 对象都是addBatch()完毕后,等待逐一执行

Mybatis的源码分析_第12张图片

CachingExecutor

先从缓存中获取查询结果,存在就返回,不存在,再委托给Executor delegate 去数据库取,delegate 可以是上面任一的SimpleExecutor、ReuseExecutor、BatchExecutor。RoutingStatementHandler,这是一个封装类,它不提供具体的实现,只是根据Executor的类型,创建不同的类型StatementHandler。
Mybatis的源码分析_第13张图片

9. StatementHandler

该类是Statement 处理器,封装了Statement 的各种数据库操作方法execute(),可见MyBatis 其实就是将操作数据库的JDBC 操作封装起来的一个框架,同时还实现了ORM 罢
了。

Mybatis的源码分析_第14张图片

10. ResultSetHandler

结果集处理器,如果是查询操作,必定会有返回结果,针对返回结果的操作,就要使用
ResultSetHandler 来进行处理,这个是由StatementHandler 来进行调用的。这个处理器的作用
就是对返回结果进行处理。

Mybatis的源码分析_第15张图片

你可能感兴趣的:(MyBatis框架,源码初窥,JAVA小窝(笔记))