How MyBatis Leverages 9 Classic Design Patterns to Simplify Java Persistence
This article explores the nine classic design patterns—Builder, Factory, Singleton, Proxy, Composite, Template Method, Adapter, Decorator, and Iterator—used throughout MyBatis, explaining each pattern's role, core classes, and how they streamline configuration, SQL execution, caching, and logging in Java backend development.
Builder Pattern
The Builder pattern separates the construction of a complex object from its representation, allowing the same construction process to create different representations. MyBatis uses builders such as SqlSessionFactoryBuilder, XMLConfigBuilder, XMLMapperBuilder, XMLStatementBuilder, and CacheBuilder to read configuration files, parse XML, and assemble the core Configuration object.
During initialization, SqlSessionFactoryBuilder invokes XMLConfigBuilder to read all MyBatis configuration and mapper XML files, building the Configuration and then a SqlSessionFactory. The builder reads files, parses XPaths, reflects objects, and caches results—tasks unsuitable for a simple constructor.
Factory Pattern
MyBatis employs a simple factory pattern for objects like SqlSessionFactory, ObjectFactory, and MapperProxyFactory. The static factory method creates instances based on input parameters, centralizing object creation.
SqlSessionacts as the core interface for executing SQL, obtaining mappers, and managing transactions, similar to a JDBC Connection. Its openSession method is overloaded to accept various parameters, delegating execution to an Executor.
Singleton Pattern
MyBatis uses the Singleton pattern for ErrorContext and LogFactory. ErrorContext provides a thread‑local singleton for recording error information per thread, while LogFactory supplies a global singleton for obtaining configured log instances.
The singleton implementation uses a private constructor, a static instance variable, and a method that creates the instance on first access. ErrorContext stores the instance in a ThreadLocal, giving each thread its own singleton.
Proxy Pattern
Proxy is the core pattern enabling MyBatis to work with mapper interfaces without manual implementation. When Configuration.getMapper is called, MyBatis creates a MapperProxy that implements InvocationHandler. Method calls on the mapper interface are delegated to this proxy, which then invokes the appropriate Executor to run SQL.
Subject: abstract mapper interface
Proxy: MapperProxy RealSubject: actual SQL execution logic
Composite Pattern
The Composite pattern organizes SQL nodes into a tree structure, allowing uniform treatment of individual and composite elements. MyBatis’s dynamic SQL nodes (e.g., TrimSqlNode, IfSqlNode, TextSqlNode) form a composite hierarchy where each node implements the same SqlNode interface.
Leaf nodes like TextSqlNode directly append SQL fragments, while container nodes like IfSqlNode evaluate conditions before delegating to child nodes.
Template Method Pattern
MyBatis’s BaseExecutor uses the Template Method pattern: the abstract class defines the overall SQL execution workflow, while concrete subclasses ( SimpleExecutor, ReuseExecutor, BatchExecutor) implement specific steps such as statement handling and batching.
Each executor strategy optimizes resource usage: SimpleExecutor creates and closes statements per operation, ReuseExecutor reuses statements keyed by SQL, and BatchExecutor batches updates for bulk execution.
Adapter Pattern
Adapter allows MyBatis to work with various logging frameworks. The Log interface defines logging methods, and concrete adapters (e.g., Log4jImpl, Slf4jImpl) wrap specific logger implementations, delegating calls to the underlying library.
Decorator Pattern
MyBatis caches are built using the Decorator pattern. The core Cache interface is implemented by PerpetualCache, and a series of decorator classes (e.g., FifoCache, LruCache, LoggingCache) add policies such as eviction, logging, serialization, and synchronization.
The decorator chain typically follows:
SynchronizedCache → LoggingCache → SerializedCache → ScheduledCache → LruCache → PerpetualCache, with optional TransactionalCache for transaction‑aware caching.
Iterator Pattern
Iterator provides a uniform way to traverse collections without exposing internal structure. MyBatis’s PropertyTokenizer implements Iterator to parse property strings, enabling iteration over tokenized parts during reflection and configuration processing.
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.
Java Backend Technology
Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!
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.
