Unveiling MyBatis: How Mapper Binding and SQL Execution Work Internally

This article dissects MyBatis 3.5.5’s internal workflow, explaining how mapper interfaces bind to XML files, the step‑by‑step SQL execution process, custom typeHandler creation for parameter and result mapping, and the underlying proxy and configuration mechanisms that drive query handling.

Code Ape Tech Column
Code Ape Tech Column
Code Ape Tech Column
Unveiling MyBatis: How Mapper Binding and SQL Execution Work Internally

Introduction

MyBatis is widely used, yet many developers are unclear about its internal SQL execution flow. This article covers four key topics: how mapper interfaces and XML files are bound, the complete SQL execution process, custom parameter handling via typeHandler, and custom result set handling.

Overview

A typical programmatic query in MyBatis looks like the following code:

SqlSession session = sqlSessionFactory.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
List<LwUser> userList = userMapper.listUserByUserName("孤狼1号");

The first line obtains a SqlSession object, the second retrieves the mapper proxy, and the third executes the query. The following sections analyse the second and third steps in depth.

Getting the Mapper Interface (getMapper)

When session.getMapper is called, MyBatis follows a runtime sequence illustrated below:

Configuration retrieves the Mapper object because all mapper interfaces are loaded and stored during application startup.

MapperRegistry inside Configuration is consulted to obtain the mapper factory.

The factory creates a JDK dynamic proxy ( MapperProxy) that implements the mapper interface.

The proxy implements InvocationHandler, enabling method interception.

When Mapper Interface and XML Are Bound

During the parsing of mybatis-config.xml, MyBatis loads mapper interfaces and their corresponding XML files. The process includes:

Calling SqlSessionFactoryBuilder.build() to create an XMLConfigBuilder.

Parsing the configuration file and the <mappers> node.

Depending on the configuration style, either the XML file is parsed directly or the mapper interface is registered first and the XML is parsed later.

Finally, Configuration.addMapper stores the mapper in knownMappers, completing the binding.

SQL Execution Process

The execution can be divided into two major steps: locating the SQL statement and executing it.

Locating the SQL

The proxy’s invoke method creates a MapperMethod object that encapsulates the method’s metadata and the associated SQL. The sequence diagram below shows this flow.

Executing the SQL

After the MapperMethod is prepared, MyBatis delegates to Executor.execute. Depending on the return type, it may call executeForMany for collections. The flow continues through StatementHandler.prepare, StatementHandler.parameterize, and finally PreparedStatement.execute. The following diagram illustrates the execution path.

Parameter Mapping

Parameter setting is performed by BaseTypeHandler subclasses. MyBatis provides default handlers (e.g., StringTypeHandler, IntTypeHandler) that call the appropriate PreparedStatement methods. Developers can create custom handlers by extending BaseTypeHandler:

package com.lonelyWolf.mybatis.typeHandler;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class MyTypeHandler extends BaseTypeHandler<String> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        System.out.println("Custom typeHandler applied");
        ps.setString(i, parameter);
    }
    // getNullableResult methods omitted for brevity
}

Using the custom handler in a mapper XML:

<select id="listUserByUserName" parameterType="String" resultMap="MyUserResultMap">
    select user_id, user_name from lw_user where user_name=#{userName,jdbcType=VARCHAR,typeHandler=com.lonelyWolf.mybatis.typeHandler.MyTypeHandler}
</select>

Running the query prints the custom handler’s log, confirming it is invoked.

Result Set Mapping

Result handling follows a similar pattern. After the JDBC ResultSet is obtained, MyBatis iterates through the rows and uses the configured typeHandler to extract column values. Custom result handlers can also be defined by overriding the getNullableResult methods in BaseTypeHandler.

public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
    System.out.println("Getting result via columnName – custom handler");
    return rs.getString(columnName);
}

The corresponding <resultMap> entry specifies the custom handler for a column:

<resultMap id="MyUserResultMap" type="lwUser">
    <result column="user_id" property="userId" jdbcType="VARCHAR" typeHandler="com.lonelyWolf.mybatis.typeHandler.MyTypeHandler"/>
    <result column="user_name" property="userName" jdbcType="VARCHAR"/>
</resultMap>

Overall Workflow Diagram

The diagram below summarises the main objects involved in a MyBatis query (SqlSession, Configuration, MapperRegistry, Executor, StatementHandler, ResultSetHandler, etc.).

Conclusion

This article analysed MyBatis’s internal SQL execution workflow, demonstrated how mapper interfaces bind to XML files, and showed how to customise parameter and result mapping with user‑defined typeHandler s. While the default handlers satisfy most scenarios, custom handlers provide a powerful extension point for special requirements.

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.

BackendJavaMyBatisSQL ExecutionmapperTypeHandler
Code Ape Tech Column
Written by

Code Ape Tech Column

Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn

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.