【Java-MyBatis】MyBatis 使用了哪些设计模式?
MyBatis框架巧妙运用了9种核心设计模式: 建造者模式:通过SqlSessionFactoryBuilder分步构建复杂配置对象 工厂模式:SqlSessionFactory生产不同特性的SqlSession实例 代理模式:MapperProxy为接口生成动态代理实现SQL转换 模板方法:BaseExecutor定义SQL执行的标准流程骨架 装饰器模式:通过Cache继承体系层层增强缓存功能

为了回答这个问题,我将先通过搜索工具获取权威资料,再结合示例详细解释MyBatis的设计模式实现。请稍候。
我发现了MyBatis框架中9个核心设计模式的实现,下面用通俗易懂的方式配合实际场景说明:
1. 建造者模式 (Builder)
// 故事:组装SQL会话工厂的乐高大师
SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(Resources.getResourceAsStream("mybatis-config.xml"));
- 作用:像组装乐高一样分步构建复杂对象(如配置对象)
- 场景:解析XML配置文件时,逐步构建Configuration对象
2. 工厂模式 (Factory)
// 故事:SQL会话制造机
try (SqlSession session = factory.openSession()) {
UserMapper mapper = session.getMapper(UserMapper.class);
}
- 作用:隐藏对象创建细节,就像自动售货机生产会话对象
- 场景:SqlSessionFactory生产SqlSession实例
3. 代理模式 (Proxy)
// 故事:Mapper接口的"替身演员"
UserMapper userMapper = session.getMapper(UserMapper.class);
userMapper.selectUser(1); // 实际调用的是代理对象
- 作用:为接口生成动态代理,拦截方法调用并转换为SQL操作
- 实现:基于JDK动态代理(
MapperProxy类)
4. 模板方法模式 (Template Method)
// 故事:SQL执行的标准流水线
public abstract class BaseExecutor implements Executor {
public <E> List<E> query(...) {
// 1. 获取缓存
// 2. 查询数据库 ← 具体步骤由子类实现
// 3. 存入缓存
}
}
- 作用:定义SQL执行骨架,具体步骤延迟到子类实现
- 子类:
SimpleExecutor/ReuseExecutor/BatchExecutor
5. 装饰器模式 (Decorator)
// 故事:给缓存穿上多层外衣
Cache cache = new LoggingCache(
new SynchronizedCache(
new PerpetualCache("userCache")));
- 作用:像洋葱一样层层包装核心功能(缓存/事务)
- 场景:通过
Cache装饰器添加日志、同步等能力
6. 责任链模式 (Chain of Responsibility)
// 故事:拦截器接力赛
@Intercepts({
@Signature(type=Executor.class, method="query", ...)
})
class PaginationInterceptor implements Interceptor {
public Object intercept(Invocation invocation) {
// 修改分页参数
return invocation.proceed(); // 传递给下一个拦截器
}
}
- 作用:拦截器链顺序处理请求(如分页/审计)
- 实现:
InterceptorChain管理拦截器调用顺序
7. 适配器模式 (Adapter)
// 故事:日志组件的万能转换器
// 将Log4j/Logback等不同日志接口统一适配为MyBatis日志接口
public class Log4j2Impl implements Log {
private final Logger log;
public void debug(String s) {
log.debug(s); // 调用具体日志实现
}
}
- 作用:统一不同日志框架的接口
- 场景:日志模块支持Log4j/SLF4J等
8. 单例模式 (Singleton)
// 故事:全局唯一的配置管家
public class Configuration {
protected static final Map<String, MappedStatement> mappedStatements
= new StrictMap<>("Mapped Statements collection");
}
- 作用:确保全局配置对象唯一性
- 实现:
Configuration在应用生命周期内单例存在
9. 策略模式 (Strategy)
// 故事:可切换的SQL执行策略
public interface Executor {
int update(MappedStatement ms, Object parameter);
}
// 具体策略:
class BatchExecutor implements Executor {...} // 批量执行
class ReuseExecutor implements Executor {...} // 复用Statement
- 作用:动态切换SQL执行算法
- 场景:根据配置选择不同的执行器策略
🌟 总结
| 设计模式 | 应用场景 | MyBatis实现类 |
|---|---|---|
| 建造者模式 | 构建复杂配置对象 | SqlSessionFactoryBuilder |
| 工厂模式 | 创建SqlSession | SqlSessionFactory |
| 代理模式 | Mapper接口动态代理 | MapperProxy |
| 模板方法 | SQL执行流程标准化 | BaseExecutor |
| 装饰器模式 | 缓存功能增强 | Cache继承体系 |
| 责任链模式 | 插件拦截器链 | InterceptorChain |
| 适配器模式 | 统一日志接口 | Log4jImpl/Slf4jImpl |
| 单例模式 | 全局配置管理 | Configuration |
| 策略模式 | 切换SQL执行策略 | Executor实现类 |
mindmap
root((MyBatis设计模式))
建造者模式
SqlSessionFactoryBuilder构建复杂对象
工厂模式
SqlSessionFactory生产SqlSession
代理模式
MapperProxy生成接口代理
模板方法
BaseExecutor定义SQL执行骨架
装饰器模式
缓存装饰链(LoggingCache→SynchronizedCache)
责任链模式
InterceptorChain管理插件调用
适配器模式
日志接口适配(Log4j/SLF4J)
单例模式
Configuration全局唯一
策略模式
Executor实现执行策略切换
以下是对MyBatis设计模式的完整解析,结合框架源码实现和实际应用场景:
深入解析MyBatis的11种设计模式
-
建造者模式(Builder)
📌 场景:组装复杂配置对象// 像拼装乐高一样构建SqlSessionFactory SqlSessionFactory factory = new SqlSessionFactoryBuilder() .build(Resources.getResourceAsStream("mybatis-config.xml"));- XML配置解析时逐步构建
Configuration对象 - 关键类:
XMLConfigBuilder,XMLMapperBuilder
- XML配置解析时逐步构建
-
工厂模式(Factory)
📌 场景:创建SqlSession实例// 像汽车工厂生产不同型号车辆 SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);- 根据参数生产不同特性的SqlSession(普通/批量)
-
代理模式(Proxy)
📌 场景:Mapper接口动态实现// 创建接口的"魔术替身" UserMapper mapper = session.getMapper(UserMapper.class);MapperProxy动态拦截方法调用,转化为SQL执行- 关键类:
MapperProxyFactory,MapperMethod
-
模板方法模式(Template Method)
📌 场景:SQL执行标准化流程public abstract class BaseExecutor { public <E> List<E> query(...) { // 1. 获取缓存(固定步骤) // 2. doQuery() ← 子类实现具体查询 // 3. 缓存结果(固定步骤) } }- 子类:
SimpleExecutor(简单查询),BatchExecutor(批量操作)
- 子类:
-
装饰器模式(Decorator)
📌 场景:缓存功能增强// 给基础缓存穿上多层外衣 Cache cache = new SynchronizedCache( // 线程安全层 new LoggingCache( // 日志记录层 new LruCache( // LRU淘汰策略 new PerpetualCache()))); // 基础缓存- 通过嵌套包装添加新功能
-
责任链模式(Chain of Responsibility)
📌 场景:插件拦截器@Intercepts(@Signature(type=StatementHandler.class, method="prepare")) class PageInterceptor implements Interceptor { public Object intercept(Invocation iv) { // 修改分页参数 return iv.proceed(); // 传递给下一个拦截器 } }InterceptorChain按序调用拦截器
-
适配器模式(Adapter)
📌 场景:统一日志接口
[外链图片转存中…(img-ZUjzn6zZ-1755870526989)]- 将Log4j/SLF4J等适配为MyBatis的Log接口
- 关键类:
Log4jImpl,Slf4jImpl
-
单例模式(Singleton)
📌 场景:全局配置管理public class Configuration { protected final Map<String, MappedStatement> mappedStatements = new StrictMap<>("Mapped Statements"); }- 整个应用生命周期内保持唯一配置实例
-
策略模式(Strategy)
📌 场景:动态SQL生成public interface SqlNode { boolean apply(DynamicContext context); }- 不同策略实现:
IfSqlNode(条件),ForEachSqlNode(循环)
- 不同策略实现:
-
迭代器模式(Iterator)
📌 场景:结果集处理try (Cursor<User> cursor = mapper.scanUsers()) { cursor.forEach(user -> process(user)); }- 通过
DefaultCursor实现大数据集的流式遍历
- 通过
-
组合模式(Composite)
📌 场景:动态SQL节点树<select> <where> <!-- 组合节点 --> <if test="name!=null">AND name=#{name}</if> <!-- 叶子节点 --> <foreach collection="ids" item="id"> <!-- 组合节点 --> OR id=#{id} </foreach> </where> </select>MixedSqlNode组合多个SqlNode实现
🌟 设计模式应用总结表
| 设计模式 | 应用场景 | 典型实现类 |
|---|---|---|
| 建造者模式 | 初始化配置 | SqlSessionFactoryBuilder |
| 工厂模式 | 创建SqlSession | SqlSessionFactory |
| 代理模式 | Mapper接口实现 | MapperProxy |
| 模板方法 | SQL执行流程 | BaseExecutor |
| 装饰器模式 | 缓存增强 | CachingExecutor |
| 责任链模式 | 插件拦截器 | InterceptorChain |
| 适配器模式 | 日志组件整合 | Log4jImpl |
| 单例模式 | 全局配置 | Configuration |
| 策略模式 | 动态SQL生成 | SqlNode实现类 |
| 迭代器模式 | 结果集遍历 | DefaultCursor |
| 组合模式 | SQL节点树 | MixedSqlNode |

💡 设计模式的价值:
- 解耦:将SQL执行、缓存处理等模块分离
- 扩展:通过拦截器链支持功能扩展
- 复用:Executor模板复用SQL执行流程
- 灵活:策略模式支持动态SQL生成
掌握这些模式能更好地理解MyBatis架构设计,编写高效插件
更多推荐

所有评论(0)