Mybatis源码-核心流程及核心类

mybatis 是一款优秀的持久层框架,简化数据库操作,包括数据库连接创建、返回结果集处理,支持动态sql,使用户可以只关心业务sql。

示例:

用户提供简单的配置文件后,就能实现对数据库操作。

java 复制代码
        // 1、创建SqlSessionFactory对象
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        // 2、由SqlSessionFactory创建一个SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 3、通过SqlSession执行对应的sql
        User user = sqlSession.selectOne("com.gang.mapper.UserMapper.selectUserById", 1);
        System.out.println(user);

核心流程

1、创建SqlSessionFactory

SqlSessionFactory作用是于生产sqlSession对象,与数据库创建连接。主要涉及配置文件的加载解析,对应mapper文件的解析。解析后数据将存储在核心对象Configuration中。你面包括了几乎所有的配置文件内容以及加载的mapper文件。配置文件中大部分配置有默认值,若是配置文件中有指定则会覆盖对应配置。

使用到的设计模式有:建造者模式、工厂模式。建造者模式用来创建复杂对象SqlSessionFactory,包含对配置文件解析封装到Configuration对象中,创建的对象为DefaultSqlSessionFactory里面有个成员变量configuration。

SqlSessionFactory为工厂类用于生产SqlSession

2、创建一个SqlSession对象

涉及事务对象和执行器对象的创建,暂时还没真正创建连接 ,执行器的创建使用到了装饰器模式,若打开了缓存则对执行器进行装饰。

包装后的执行器执行query方法前会执行增强逻辑:判断有没有缓存类cache,再判断缓存中是否有数据,若没有缓存内或者缓存中没有数据在走BaseExecutor中的query

缓存类cache是解析mapper文件时是否添加了cache标签

有标签会添加cache类,cache便签还可以指定自定义缓存类(type属性),需实现Cache接口,若未指定默认为PERPETUAL

PERPETUAL是PerpetualCache的别名,在Configuration类中有指定

一级缓存,默认是PerpetualCache,在每个SqlSession对象内部,作用范围是一次会话内有效。

二级缓存可以自己指定,不指定默认是经过包装后的PerpetualCache。

二级缓存是在Configuration 中存储同时MappedStatement中也持有缓存对象的应用,作用域为进程级别,支持跨session。

一级缓存默认打开,且线程安全。二级缓存需要缓存类自己保证相应规则,Mybatis的cache包下默认提供了10个缓存包装类分别实现不同功能,若想使用可自行选择。

配置文件中settings标签的cacheEnabled是全局性地开启或关闭所有映射器配置文件中已配置的任何缓存(是否打开mapper文件中的cache便签)。因为二级缓存是根据mapper维度设置的,可以使用 使多个mapper共享相同的缓存配置和实例。

3、执行查询返回结果

包含创建数据库连接,执行相应的查询,本处理返回结果,将结果映射为对象。

doQuery方法中会由事务对象的到数据库连接。

若打日志打开了debug连接对象将由ConnectionLogger代理,在执行sql时会打印sql语句。日志实现类可在配置文件中指定,StdOutImpl类将忽略日志等级,所有日志都会打印到控制台。返回列及具体值是trace级日志等级若是debug及以上则不会输出。

Mybatis中的核心类

一、构建初始化阶段(解析配置,生成 SqlSessionFactory)

SqlSessionFactoryBuilder :建造者角色,解析配置输入流,构建出 SqlSessionFactory。

XMLConfigBuilder :解析 mybatis‑config.xml 全局配置文件,生成 Configuration。内部会创建 XMLMapperBuilder 解析各个 Mapper 映射文件。

XMLMapperBuilder :解析 Mapper.xml,解析标签等,生成MappedStatement。

Configuration :【全局大管家】MyBatis 的总配置对象,所有配置全部存在这里。保存 settings、数据源、环境、别名、插件、Mapper 映射、二级缓存集合、所有 MappedStatement。

SqlSessionFactory (接口) & DefaultSqlSessionFactory(实现类):工厂接口,生产 SqlSession。

二、会话层(与应用交互)

SqlSession (接口) & DefaultSqlSession(实现类):对外提供 CRUD 方法:selectOne、selectList、update、insert、delete、commit、rollback、close。持有:Configuration、Executor、一级缓存localCache。生命周期:请求 / 方法级别,用完关闭(一级缓存 PerpetualCache 就在 DefaultSqlSession 内部)。

MapperProxyFactory :生成 Mapper 代理对象。

MapperProxy :实现InvocationHandler,代理 Mapper 接口方法,方法调用转发给sqlSession。

调用 mapper 接口方法本质:mapperProxy.invoke() → 调用sqlSession.selectOne/selectList。

三、事务相关

Transaction(接口) & JdbcTransaction(实现):管理 JDBC Connection;延迟获取连接。

openSession 创建 Transaction 对象,但此时不拿连接;真正执行 SQL 才去 DataSource 拿 Connection。

TransactionFactory:生产 Transaction 对象;JdbcTransactionFactory。

四、Executor 执行器层(MyBatis 核心调度,装饰器模式)

Executor(接口):核心方法:query()、update()、commit()、rollback()。

实现类:

BaseExecutor:抽象基类,实现一级缓存逻辑。

SimpleExecutor:默认,每执行一次语句创建新 Statement。

ReuseExecutor:复用 Statement 对象。

BatchExecutor:批量操作,批量提交。

CachingExecutor:装饰器,负责二级缓存逻辑,包装上面 3 种 Executor。

openSession 中 configuration.newExecutor():cacheEnabled=true,就用 CachingExecutor 包装底层执行器。

五、缓存相关

Cache(接口):缓存统一接口。

PerpetualCache:默认底层实现,内部 HashMap。

装饰实现:LruCache、SynchronizedCache、LoggingCache(二级缓存多层装饰)。

CacheKey:缓存 key 对象,由 sql、参数、分页、环境等信息组合生成,用于一二级缓存 key。

六、Statement 处理器、参数、结果集处理器(三大处理器)

StatementHandler(接口):封装 JDBC Statement 操作。

实现:PreparedStatementHandler(最常用)、SimpleStatementHandler、CallableStatementHandler。

职责:创建 prepareStatement,调用下面两个处理器。

ParameterHandler:设置 SQL 参数,把 Java 参数填充到 PreparedStatement。对应日志打印 Parameters。

ResultSetHandler:处理 JDBC ResultSet 结果集,封装为 Java 实体对象。

三大处理器都会经过插件拦截链,MyBatis 插件就是拦截这四个对象:Executor、StatementHandler、ParameterHandler、ResultSetHandler。

七、映射对象

MappedStatement:保存一条 SQL 的全部元数据,每个<select/update>标签对应一个 MappedStatement。

里面包含:sql、参数类型、返回类型、cache、sqlCommandType 等。存放在 Configuration。

BoundSql:保存解析完成的 SQL(? 占位符 sql)、参数映射信息。动态 SQL 解析后生成 BoundSql。

八、Spring 整合特有类(补充)

SqlSessionTemplate:Spring 对 SqlSession 的代理,线程安全;内部持有SqlSessionFactory。

不会真正关闭自身,通过 ThreadLocal 绑定 SqlSession。

结构图:

java 复制代码
SqlSessionFactoryBuilder.build(inputStream)
    →XMLConfigBuilder解析 →Configuration
SqlSessionFactory.openSession()
    →创建Transaction
    →Configuration.newExecutor() 得到CachingExecutor/SimpleExecutor
    →new DefaultSqlSession
SqlSession.selectOne()
    →MapperProxy代理调用
    →Executor.query()(一二级缓存)
        →StatementHandler
            →ParameterHandler 设置参数
            →ResultSetHandler 封装结果```
相关推荐
zzh___zzh1 小时前
Java Stream API 常用方法笔记
java·笔记
萌动的小火苗1 小时前
1、python基础面试题
java·开发语言·python
麻雀聊技术2 小时前
一重启 AI 就失忆?用 Spring AI + PostgreSQL 3步搞定“长期记忆”持久化(附完整代码)
java·spring·openai
码农进化录2 小时前
Java 程序员的 AI 进化论 | LangChain4j 入门,Java 开发者的 AI 应用框架
java·spring boot·openai
番茄炒鸡蛋加糖3 小时前
中级核心技术1--MySQL/Java 并发
java·数据库·mysql
he___H3 小时前
Spring-Configur注解
java·spring
SunnyDays10113 小时前
Java 如何为 PDF 添加、修改和删除书签
java·pdf
铃木之影4 小时前
Java 版本 RAG 示例(Spring AI + Milvus)
java·人工智能·spring
C++、Java和Python的菜鸟4 小时前
第14章 项目部署(Linux)
java