Understanding MyBatis: Concepts, Advantages, Disadvantages, Usage Scenarios, and Advanced Features

This article provides a comprehensive overview of MyBatis, a semi‑ORM Java framework, covering its core concepts, benefits, drawbacks, appropriate use cases, differences from Hibernate, parameter handling, dynamic SQL, caching, lazy loading, mapper binding, plugin development, and various configuration techniques.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Understanding MyBatis: Concepts, Advantages, Disadvantages, Usage Scenarios, and Advanced Features

1. What is MyBatis?

MyBatis is a semi‑ORM (Object‑Relational Mapping) framework that encapsulates JDBC, allowing developers to focus on writing native SQL without dealing with driver loading, connection creation, or statement management, thus offering precise control over SQL performance.

It supports XML or annotation‑based configuration to map POJOs to database records, eliminating most JDBC boilerplate code.

SQL statements are defined in XML files or annotations; MyBatis binds Java object properties to dynamic SQL parameters, executes the SQL, and maps the results back to Java objects.

2. Advantages of MyBatis

SQL‑centric programming provides high flexibility and does not affect existing application or database design; SQL placed in XML decouples it from code for unified management, and XML tags support dynamic and reusable SQL.

Compared with raw JDBC, MyBatis reduces code volume by more than 50 % and removes the need for manual connection handling.

It works with any JDBC‑supported database, ensuring broad compatibility.

Seamless integration with Spring is available.

Mapping tags enable object‑to‑database field mapping, simplifying ORM relationships.

3. Disadvantages of MyBatis

Writing SQL can be labor‑intensive, especially for tables with many columns or complex joins, requiring solid SQL skills.

SQL statements are tied to a specific database, which can hinder portability when switching databases.

4. Suitable Scenarios for MyBatis

Ideal for projects that prioritize SQL control and performance, or where requirements change frequently (e.g., internet applications).

5. Differences Between MyBatis and Hibernate

MyBatis is not a full ORM; developers write SQL manually, offering fine‑grained performance control but requiring more effort for database‑independent code.

Hibernate provides automatic ORM capabilities and better database independence, reducing code for complex relational models.

6. Difference Between #{} and ${}

#{}

is a prepared‑statement placeholder; MyBatis replaces it with a "?" and sets the value via PreparedStatement, protecting against SQL injection. ${} performs direct string substitution, inserting the variable value into the SQL, which can lead to injection risks.

7. Handling Mismatched Property and Column Names

Method 1: Use column aliases in the SQL to match Java property names.

<select id="selectorder" parameterType="int" resultType="me.gacl.domain.order">
    select order_id id, order_no orderno, order_price price
    from orders
    where order_id=#{id}
</select>

Method 2: Define a <resultMap> that maps each column to the corresponding property.

<resultMap type="me.gacl.domain.order" id="orderresultmap">
    <id property="id" column="order_id"/>
    <result property="orderno" column="order_no"/>
    <result property="price" column="order_price"/>
</resultMap>

8. Writing a LIKE Fuzzy Query

Method 1: Add the wildcard in Java code and use #{value} in the mapper.

String wildcardName = "%smi%";
List<Name> names = mapper.selectLike(wildcardName);

<select id="selectlike" resultType="Name">
    SELECT * FROM foo WHERE bar LIKE #{value}
</select>

Method 2: Concatenate the wildcard directly in the SQL (prone to injection).

String name = "smi";
List<Name> names = mapper.selectLike(name);

<select id="selectlike" resultType="Name">
    SELECT * FROM foo WHERE bar LIKE "%"#{value}"%"
</select>

9. Mapper Interface Mechanics

The fully qualified name of a Mapper interface matches the namespace attribute in the XML file; each method name corresponds to a statement id. MyBatis creates a JDK dynamic proxy for the interface; invoking a method triggers the proxy to locate the associated MapperStatement and execute the bound SQL.

10. Pagination in MyBatis

MyBatis provides RowBounds for in‑memory pagination and supports physical pagination via custom SQL or pagination plugins. Plugins intercept the SQL execution, rewrite it according to the database dialect, and add appropriate LIMIT/OFFSET clauses.

11. Result Mapping Strategies

Two main approaches: (1) Define a <resultMap> that explicitly maps columns to object fields; (2) Use column aliases that match Java property names. MyBatis then uses reflection to instantiate objects and set field values.

12. Batch Insert Execution

Define a simple insert statement in XML and open a session with ExecutorType.BATCH to execute multiple inserts efficiently.

<insert id="insertname">
    INSERT INTO names (name) VALUES (#{value})
</insert>

List<String> names = Arrays.asList("fred", "barney", "betty");
SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
try {
    NameMapper mapper = session.getMapper(NameMapper.class);
    for (String n : names) {
        mapper.insertname(n);
    }
    session.commit();
} finally {
    session.close();
}

13. Retrieving Auto‑Generated Keys

Set useGeneratedKeys="true" and specify keyProperty in the insert tag; MyBatis will populate the generated key into the parameter object after execution.

<insert id="insertname" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO names (name) VALUES (#{name})
</insert>

14. Passing Multiple Parameters

Method 1: Use positional placeholders #{0}, #{1} in the XML.

public User selectUser(String name, String area);

<select id="selectUser" resultMap="BaseResultMap">
    SELECT * FROM user_user_t WHERE user_name = #{0} AND user_area = #{1}
</select>

Method 2: Annotate parameters with @Param("name") and reference them by name.

Method 3: Wrap parameters in a Map and pass the map to the mapper.

15. Dynamic SQL in MyBatis

Dynamic SQL tags ( trim, where, set, foreach, if, choose, when, otherwise, bind) allow conditional construction of SQL statements based on runtime expressions.

16. Additional XML Tags

Beyond select, insert, update, delete, MyBatis supports <resultMap>, <parameterMap>, <sql>, <include>, <selectKey>, and the nine dynamic‑SQL tags.

17. ID Uniqueness Across Mapper Files

If a namespace is defined, statement id s may repeat across files; without a namespace, id must be unique because the key is namespace+id.

18. MyBatis as a Semi‑Automatic ORM

Unlike full‑automatic ORM tools such as Hibernate, MyBatis requires developers to write SQL manually, offering more control but less automation.

19. One‑to‑One and One‑to‑Many Associations

Use <association> for one‑to‑one and <collection> for one‑to‑many mappings inside a <resultMap>. Queries can be performed via joint SQL or nested selects.

20. Implementing One‑to‑One

Two approaches: (1) Joint query with an <association> node; (2) Nested query where the second select is referenced via the select attribute of <association>.

21. Implementing One‑to‑Many

Similar to one‑to‑one, using either a joint query with a <collection> node or a nested query where the collection’s select attribute points to a separate statement.

22. Lazy Loading Support

MyBatis can lazily load association (one‑to‑one) and collection (one‑to‑many) objects when lazyLoadingEnabled=true. It creates CGLIB proxies that fetch the related data on first access.

23. First‑Level and Second‑Level Caches

First‑level cache: Session‑scoped PerpetualCache (HashMap) cleared on session close/flush. Second‑level cache: Namespace‑scoped, also PerpetualCache by default, configurable with external providers (e.g., Ehcache) via <cache/> in the mapper.

24. Mapper Interface Binding

Two binding methods: (1) Annotation‑based binding using @Select, @Update, etc.; (2) XML‑based binding where the mapper’s fully qualified name matches the XML namespace.

25. Requirements for Mapper Interface Calls

Method name must match the statement id in XML.

Method parameter types must match the statement parameterType.

Method return type must match the statement resultType or resultMap.

The XML namespace must be the mapper’s fully qualified class name.

26. Ways to Create Mappers

1) Extend SqlSessionDaoSupport and configure mapper XML in sqlMapConfig.xml. 2) Use MapperFactoryBean to generate proxies. 3) Enable mapper scanning with MapperScannerConfigurer so Spring automatically registers mapper interfaces.

27. MyBatis Plugin Mechanism

Plugins can intercept four core interfaces: ParameterHandler, ResultSetHandler, StatementHandler, and Executor. MyBatis creates JDK dynamic proxies for these interfaces; the plugin implements Interceptor and defines which methods to intercept via annotations.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendJavaSQLPersistenceMyBatisORM
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.