Unlocking MyBatis: 10+ Design Patterns Powering Its Architecture
This article dissects MyBatis's source code, revealing how more than ten classic design patterns—such as Factory, Singleton, Builder, Adapter, Proxy, Composite, Decorator, Template, Strategy, and Iterator—are applied to decouple complex scenarios, improve extensibility, and streamline ORM operations.
MyBatis's over‑20,000 lines of framework code heavily employ classic design patterns to solve complex architectural problems. By cataloguing these patterns, the article shows how each contributes to decoupling, extensibility, and maintainability.
Factory Pattern (Creational)
Structure of SqlSessionFactory is illustrated in Figure 2. The factory method creates session objects, allowing subclasses to decide the concrete type. Scenario: Every time MyBatis accesses the database, a new session is opened; the factory gathers data‑source configuration, builds a transaction factory, creates an executor, and returns the session implementation.
Related classes: SqlSessionFactory, ObjectFactory, MapperProxyFactory, DataSourceFactory.
Singleton Pattern (Creational)
Figure 3 shows the structure of the Configuration singleton. This pattern guarantees a single instance and provides a global access point.
Scenario: Configuration is a large singleton that lives throughout the session lifecycle, initializing all configuration objects (mappings, caches, interceptors, factories, etc.) during the SqlSessionFactoryBuilder construction phase.
Related classes: ErrorContext, LogFactory, Configuration.
Builder Pattern (Creational)
Figure 4 depicts the ResultMap builder. The builder assembles complex objects step‑by‑step using simple sub‑objects, keeping object construction separate from business logic.
Scenario: MyBatis uses many *Builder classes (e.g., SqlSessionFactoryBuilder, XMLConfigBuilder, XMLMapperBuilder, XMLStatementBuilder, CacheBuilder) to parse XML files into object graphs, isolating configuration concerns from core processing.
Adapter Pattern (Structural)
Figure 5 shows the logging implementation hierarchy. The adapter enables incompatible logging APIs (Log4j, Log4j2, SLF4J, etc.) to cooperate with MyBatis through a unified interface.
Related scenario: Unifying disparate logging frameworks under a common MyBatis logging contract.
Proxy Pattern (Structural)
Figure 6 illustrates the proxy implementation. A proxy supplies a placeholder that controls access to the real object, allowing pre‑processing before delegating calls.
Scenario: MyBatis's MapperProxy generates dynamic implementations of DAO interfaces; every CRUD method call is intercepted by the proxy, which then delegates to the executor and returns the database result.
Related classes: DriverProxy, Plugin, Invoker, MapperProxy.
Composite Pattern (Structural)
Figure 7 displays the node hierarchy used for dynamic SQL. The composite lets objects be composed into a tree structure representing “part‑whole” relationships.
Scenario: MyBatis XML dynamic SQL provides nine tags (trim, where, set, foreach, if, choose, when, otherwise, bind). Each tag corresponds to a SqlNode implementation; the tree of SqlNode objects is assembled to generate the final SQL.
Related classes: Various SqlNode subclasses handling different tags.
Decorator Pattern (Structural)
Figure 8 shows the second‑level cache decorator. The decorator wraps a simple executor, adding caching behavior without altering the executor's core logic.
Scenario: All MyBatis SQL operations go through SimpleExecutor. The second‑level cache is built by wrapping the simple executor with a cache executor, effectively applying the decorator (also known as the Russian‑doll pattern).
Template Method Pattern (Behavioral)
Figure 9 presents the SQL execution template. The abstract class BaseExecutor defines the overall algorithm, while subclasses override specific steps.
Scenario: Standardizing the workflow for query and update operations; BaseExecutor provides the skeleton, and concrete executors (e.g., SimpleExecutor, CachingExecutor) implement the variable parts.
Strategy Pattern (Behavioral)
Figure 10 shows the type‑handler strategy hierarchy. Each algorithm for handling a specific Java type is encapsulated in its own class, allowing interchangeable use.
Scenario: When MyBatis processes JDBC results, it selects a TypeHandler implementation based on the target Java type, avoiding massive if chains.
Related classes: PooledDataSource, UnpooledDataSource, BatchExecutor, ReuseExecutor, SimpleExecutor, CachingExecutor, LongTypeHandler, StringTypeHandler, DateTypeHandler.
Iterator Pattern (Behavioral)
Figure 11 illustrates the PropertyTokenizer implementation. The iterator traverses a collection without exposing its underlying representation.
Scenario: PropertyTokenizer is used throughout MyBatis for parsing object property paths, handling configuration parsing, parameter binding, and object setting.
Related class: PropertyTokenizer.
Summary
By cataloguing the patterns, the article concludes that MyBatis employs roughly ten design patterns, demonstrating how a sophisticated ORM framework leverages classic architectural solutions to manage complexity. Understanding these patterns helps developers grasp advanced framework design, improve coding thinking, and become better architects.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Architect
Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
