一个用于学习 MyBatis / mybatis-spring 核心机制的迷你多模块项目。
这个仓库不是为了实现完整框架,而是把最关键的主链路拆出来:从 JDBC 和 DAO 层的重复劳动出发,理解 MyBatis 如何把 Mapper 接口调用变成 SQL 执行,再理解 mybatis-spring 如何把 Mapper 代理注册成 Spring Bean。
mini-mybatis-parent
├── mini-mybatis 原生 MyBatis 核心机制
└── mini-mybatis-spring mini 版 org.mybatis:mybatis-spring:3.0.0 适配层
mini-mybatis 负责 SQL 执行主链路:
SqlSessionFactory/SqlSession- Mapper 接口动态代理
@Select/@Insert/@Update/@Delete注解映射- XML mapper 映射
#{}参数绑定到PreparedStatementResultSet按列名映射到 JavaBean
mini-mybatis-spring 负责 Spring 集成主链路:
SqlSessionFactoryBeanSqlSessionTemplateMapperFactoryBean@MapperScan
flowchart TB;
subgraph ApplicationLayer;
Service[业务代码];
Mapper[Mapper接口];
end;
subgraph SessionProxyLayer;
Factory[MiniSqlSessionFactory];
Session[SqlSession];
Proxy[MapperProxy];
end;
subgraph MappingLayer;
Config[Configuration];
Statement[MappedStatement];
SqlSource[注解和XML SQL];
end;
subgraph SqlExecutionLayer;
Parser[SqlSourceParser];
Executor[SimpleExecutor];
ResultMap[结果映射];
end;
subgraph DatabaseLayer;
JDBC[DataSource和JDBC];
DB[(Database)];
end;
Service --> Mapper;
Mapper --> Proxy;
Factory --> Session;
Session --> Proxy;
SqlSource --> Config;
Config --> Statement;
Proxy --> Statement;
Proxy --> Session;
Session --> Executor;
Statement --> Parser;
Parser --> Executor;
Executor --> JDBC;
JDBC --> DB;
DB --> JDBC;
JDBC --> ResultMap;
ResultMap --> Service;
一次原生 Mapper 调用可以简化为:
mapper.findById(1L)
-> MapperProxy
-> MappedStatement
-> SqlSourceParser
-> SimpleExecutor
-> JDBC
-> ResultSet 映射
flowchart TB;
subgraph SpringApplicationLayer;
ConfigClass[Configuration];
MapperScan[MapperScan];
UserService[Service];
MapperBean[UserMapper Bean];
end;
subgraph MyBatisSpringAdapterLayer;
SFB[SqlSessionFactoryBean];
Template[SqlSessionTemplate];
Registrar[MapperScannerRegistrar];
Scanner[SimpleMapperScanner];
MFB[MapperFactoryBean];
end;
subgraph NativeMiniMyBatisLayer;
NativeFactory[MiniSqlSessionFactory];
NativeSession[SqlSession];
NativeProxy[MapperProxy];
NativeExecutor[Executor和JDBC];
end;
ConfigClass --> SFB;
ConfigClass --> Template;
MapperScan --> Registrar;
Registrar --> Scanner;
Scanner --> MFB;
SFB --> NativeFactory;
Template --> NativeFactory;
MFB --> Template;
MFB --> MapperBean;
UserService --> MapperBean;
MapperBean --> Template;
Template --> NativeSession;
NativeSession --> NativeProxy;
NativeProxy --> NativeExecutor;
Spring 集成后的核心变化是:
Mapper 接口
-> @MapperScan 注册 MapperFactoryBean
-> MapperFactoryBean 暴露 Mapper 代理
-> SqlSessionTemplate 管理 SqlSession 调用
-> 复用原生 mini-mybatis 执行链路
mvn test也可以只运行单个模块:
mvn -pl mini-mybatis test
mvn -pl mini-mybatis-spring testMiniSqlSessionFactory factory = new MiniSqlSessionFactoryBuilder()
.dataSource(dataSource)
.addMapper(UserMapper.class)
.addXmlMapper("mapper/UserXmlMapper.xml")
.build();
try (SqlSession session = factory.openSession()) {
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.findById(1L);
}@Configuration
@MapperScan("com.example.mapper")
class AppConfig {
@Bean
SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setMapperInterfaces(new Class<?>[]{UserMapper.class});
factoryBean.setMapperLocations(new String[]{"mapper/UserMapper.xml"});
return factoryBean;
}
@Bean
SqlSessionTemplate sqlSessionTemplate(MiniSqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}之后业务代码可以直接从 Spring 容器注入 Mapper:
class UserService {
private final UserMapper userMapper;
UserService(UserMapper userMapper) {
this.userMapper = userMapper;
}
}mini-mybatis:
- MiniSqlSessionFactoryBuilder
- DefaultSqlSession
- MapperProxy
- MappedStatement
- SqlSourceParser
- SimpleExecutor
mini-mybatis-spring:
- SqlSessionFactoryBean
- SqlSessionTemplate
- MapperFactoryBean
- MapperScan
- MapperScannerRegistrar
- SimpleMapperScanner
当前已支持:
- 静态 SQL
#{}占位符- 注解 Mapper
- XML Mapper
- JDK 动态代理
- 简单 JavaBean 映射
- 基础增删改查
- Spring
FactoryBean集成 - 简单
@MapperScan
暂不包含:
- 动态 SQL,如
<if>、<where>、<foreach> - 一级缓存、二级缓存
- 插件拦截器
- TypeHandler 注册表
- 复杂 ResultMap
- Spring 事务同步
- 异常翻译
- Spring Boot 自动配置