设计模式在MyBatis中的具体应用与分析

发布于:2025-03-15 ⋅ 阅读:(18) ⋅ 点赞:(0)

在这里插入图片描述

一、设计模式应用

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接口的实现类(LruCacheLoggingCache)通过装饰器增强缓存行为。
  • 实现方式
    PerpetualCache为基础缓存,其他装饰器(如LruCache)通过组合方式添加缓存策略。
  • 代码示例
    public class LruCache implements Cache {
        private final Cache delegate;
        public LruCache(Cache delegate) { this.delegate = delegate; }
        // 添加LRU淘汰策略逻辑
    }
    

2.3 适配器模式

  • 应用场景
    日志框架的兼容,如Log接口适配Log4jSlf4j等不同日志实现。
  • 实现方式
    通过Log4jImplSlf4jImpl等适配类将第三方日志接口转换为MyBatis定义的Log接口。
  • 代码示例
    public class Log4jImpl implements Log {
        private final Logger logger;
        public Log4jImpl(String clazz) { logger = Logger.getLogger(clazz); }
    }
    

3. 行为型模式

3.1 模板方法模式

  • 应用场景
    SQL执行流程的标准化,如BaseExecutor定义执行模板,子类(SimpleExecutorBatchExecutor)实现具体逻辑。
  • 实现方式
    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接口针对不同数据类型(StringDate)选择对应的处理策略。
  • 实现方式
    每个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();
        }
    }
    

二 、总结对比

设计模式 应用场景 关键实现
工厂模式 创建SqlSessionFactoryObjectFactory 隔离复杂对象的创建逻辑,统一入口
建造者模式 解析XML构建Configuration对象 分步处理复杂配置,支持多层级嵌套解析
代理模式 Mapper接口的动态代理 解耦接口定义与SQL执行逻辑,实现无侵入式扩展
装饰器模式 缓存功能增强(LRU、日志、同步) 动态扩展对象功能,避免继承导致的类爆炸问题
模板方法模式 SQL执行流程标准化(BaseExecutor 抽象公共逻辑,子类差异化实现具体步骤
责任链模式 插件机制(拦截SQL执行) 通过动态代理链实现多插件的顺序执行

设计模式的价值
MyBatis通过灵活运用设计模式,将复杂逻辑(如配置解析、SQL执行、缓存管理)模块化,显著提升了代码的可扩展性和可维护性。例如,插件机制通过责任链模式支持动态扩展,而代理模式使得Mapper接口与实现完全解耦,体现了“面向接口编程”的核心思想。这些模式的应用不仅简化了框架设计,也为开发者提供了清晰的功能扩展路径。