设计模式在MyBatis中的具体应用与分析
设计模式在MyBatis中的具体应用与分析
一、设计模式应用
1. 创建型模式
1.1 工厂模式
应用场景 :
MyBatis通过工厂模式创建核心对象,如
SqlSessionFactory
(用于生成SqlSession
)、ObjectFactory
(负责实例化结果对象)、MapperProxyFactory
(动态生成Mapper接口的代理对象)。实现方式 :
SqlSessionFactoryBuilder
解析配置文件(mybatis-config.xml
)后构建SqlSessionFactory
,隔离了配置解析的复杂性。代码示例 :
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
1.2 单例模式
应用场景 :
确保全局唯一性,如
Configuration
(核心配置对象)、ErrorContext
(线程级错误上下文)、LogFactory
(日志工厂)。实现方式 :
Configuration
在MyBatis初始化时仅创建一次,贯穿整个生命周期;ErrorContext
通过ThreadLocal
实现线程级单例。代码示例 :
public class LogFactory { private static LogFactory instance = new LogFactory(); private LogFactory() {} public static LogFactory getInstance() { return instance; } }
1.3 建造者模式
应用场景 :
复杂对象的构建,如
XMLConfigBuilder
解析XML配置构建Configuration
对象,XMLStatementBuilder
解析SQL语句生成MappedStatement
。实现方式 :
通过链式调用和分步构建,解决多层级配置解析问题。
代码示例 :
public class SqlSessionFactoryBuilder { public SqlSessionFactory build(InputStream inputStream) { XMLConfigBuilder parser = new XMLConfigBuilder(inputStream); return build(parser.parse()); } }
2. 结构型模式
2.1 代理模式
应用场景 :
Mapper接口的动态代理实现,如
MapperProxy
通过JDK动态代理将接口方法调用转发为SQL执行。实现方式 :
MapperProxy
实现InvocationHandler
接口,拦截接口方法调用并调用SqlSession
的CRUD方法。代码示例 :
public class MapperProxy<T> implements InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) { // 转换为SQL执行逻辑 return sqlSession.selectOne(statementId, args); } }
2.2 装饰器模式
应用场景 :
缓存功能的扩展,如
Cache
接口的实现类(LruCache
、LoggingCache
)通过装饰器增强缓存行为。实现方式 :
PerpetualCache
为基础缓存,其他装饰器(如LruCache
)通过组合方式添加缓存策略。代码示例 :
public class LruCache implements Cache { private final Cache delegate; public LruCache(Cache delegate) { this.delegate = delegate; } // 添加LRU淘汰策略逻辑 }
2.3 适配器模式
应用场景 :
日志框架的兼容,如
Log
接口适配Log4j
、Slf4j
等不同日志实现。实现方式 :
通过
Log4jImpl
、Slf4jImpl
等适配类将第三方日志接口转换为MyBatis定义的Log
接口。代码示例 :
public class Log4jImpl implements Log { private final Logger logger; public Log4jImpl(String clazz) { logger = Logger.getLogger(clazz); } }
3. 行为型模式
3.1 模板方法模式
应用场景 :
SQL执行流程的标准化,如
BaseExecutor
定义执行模板,子类(SimpleExecutor
、BatchExecutor
)实现具体逻辑。实现方式 :
BaseExecutor
抽象类定义doUpdate()
、doQuery()
等模板方法,由子类实现。代码示例 :
public abstract class BaseExecutor { public <E> List<E> query(...) { // 公共逻辑 return doQuery(ms, parameter, rowBounds, resultHandler, boundSql); } protected abstract <E> List<E> doQuery(...); }
3.2 策略模式
应用场景 :
参数类型处理,如
TypeHandler
接口针对不同数据类型(String
、Date
)选择对应的处理策略。实现方式 :
每个
TypeHandler
实现类(如StringTypeHandler
)定义特定类型的数据转换逻辑。代码示例 :
public interface TypeHandler<T> { void setParameter(PreparedStatement ps, int i, T parameter) throws SQLException; }
3.3 责任链模式
应用场景 :
插件机制(如分页、性能监控),通过
InterceptorChain
形成代理链拦截目标方法。实现方式 :
插件实现
Interceptor
接口,InterceptorChain
通过动态代理生成多层代理对象。代码示例 :
public class PageInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { // 修改SQL逻辑 return invocation.proceed(); } }
二 、总结对比
设计模式 | 应用场景 | 关键实现 |
---|---|---|
工厂模式 | 创建 SqlSessionFactory 、 ObjectFactory | 隔离复杂对象的创建逻辑,统一入口 |
建造者模式 | 解析XML构建 Configuration 对象 | 分步处理复杂配置,支持多层级嵌套解析 |
代理模式 | Mapper接口的动态代理 | 解耦接口定义与SQL执行逻辑,实现无侵入式扩展 |
装饰器模式 | 缓存功能增强(LRU、日志、同步) | 动态扩展对象功能,避免继承导致的类爆炸问题 |
模板方法模式 | SQL执行流程标准化( BaseExecutor ) | 抽象公共逻辑,子类差异化实现具体步骤 |
责任链模式 | 插件机制(拦截SQL执行) | 通过动态代理链实现多插件的顺序执行 |
设计模式的价值 :
MyBatis通过灵活运用设计模式,将复杂逻辑(如配置解析、SQL执行、缓存管理)模块化,显著提升了代码的可扩展性和可维护性。例如,插件机制通过责任链模式支持动态扩展,而代理模式使得Mapper接口与实现完全解耦,体现了“面向接口编程”的核心思想。这些模式的应用不仅简化了框架设计,也为开发者提供了清晰的功能扩展路径。