MyBatis 用到哪些设计模式?¶
一、建造者模式(Builder)¶
SqlSessionFactoryBuilder、XMLConfigBuilder、XMLMapperBuilder 都用建造者模式解析复杂的 XML 配置,把"配置加载"与"对象构建"分离。
二、工厂模式¶
SqlSessionFactory:工厂接口,生产SqlSession。MapperProxyFactory:为每个 Mapper 接口生产代理实例。
SqlSession session = factory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
三、代理模式¶
MyBatis 不需要写 Mapper 实现类,接口方法调用被 MapperProxy(实现 InvocationHandler)拦截,最终执行 SQL:
public class MapperProxy<T> implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) {
// 转成 MapperMethod,执行 SqlSession.select/update
}
}
四、模板方法¶
BaseExecutor 实现了"获取连接、参数绑定、结果集处理"流程,把 doUpdate/doQuery 交给子类:
SimpleExecutorReuseExecutorBatchExecutor
五、适配器¶
ParameterHandler、ResultSetHandler 适配不同的 JDBC 类型与 Java 类型。
六、装饰器 / 包装器¶
Cache 接口有多种实现,层层包装:
这是典型的装饰器模式,给原始 Cache 动态加 LRU、日志、同步等能力。
七、责任链¶
插件(Interceptor)用责任链包装四大对象(Executor、ParameterHandler、ResultSetHandler、StatementHandler):
八、策略模式¶
LanguageDriver:处理 SQL 脚本。Logging:选择用 Log4j、Slf4j 还是 JDK logging。TypeHandler:每种 Java 类型与 JDBC 类型的转换策略。
九、单例¶
Configuration 在整个 SqlSessionFactory 中是单例。
高频追问
- 为什么 Mapper 接口不用写实现类?因为 JDK 动态代理
MapperProxy。 - 一级缓存和二级缓存:一级是
Executor级,SqlSession 关闭就没;二级是Mapper级,跨 SqlSession,但生产环境几乎不用(容易脏数据)。