Understanding MyBatis Mapper Dynamic Proxy Implementation

SQL Execution Flow Recap

Standard MyBatis execution involves explicit DAO implementation classes handling SQL execution. The typical flow requires:

  1. Defining a DAO interface
  2. Implementing the interface with explicit SQL execution logic
  3. Manually mapping method names to SQL statement IDs

This manual mapping creates unnecessary boilerplate code. The dynamic proxy approach eliminates this step by automatically linking interface methods to SQL statements.

Dynamic Proxy Configuration

Configure your MyBatis configuration to enable dynamic proxies:

<configuration>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
        <property name="username" value="root"/>
        <property name="password" value="password"/>
      </dataSource>
    </environment>
  </environments>
  
  <mappers>
    <mapper resource="com/example/mapper/StudentMapper.xml"/>
  </mappers>
</configuration>

Define your mapper interface with the same fully qualified name as the XML namespace:

package com.example.mapper;

public interface StudentMapper {
    List<Map<String, Object>> findStudentsByDepartment(String deptId);
}

Configure the mapper XML with the interface's fully qualified name as the namespace:

<?xml version="1.0" encoding="UTF-8" ?>
<mapper namespace="com.example.mapper.StudentMapper">
  <select id="findStudentsByDepartment" resultType="map">
    SELECT * FROM students WHERE department_id = #{deptId}
  </select>
</mapper>

Retrieve the proxy instance using:

SqlSession session = sqlSessionFactory.openSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);

Proxy Implementation Mechanics

When getMapper() is callled, MyBatis executes the following flow:

  1. Configuration retrieves the MapperProxyFactory for the target interface
  2. Factory creates a MapperProxy instance bound to the current SqlSession
  3. Proxy.newProxyInstance() generates a dynamic proxy wrapping the interface

The proxy intercepts method calls and routes them to the corresponding SQL statement using the method name as the statement ID. For result handling:

  • Collection return types automatically use selectList()
  • Single object types default to selectOne()

For map results, ensure the return type matches the expected collecsion structure to avoid type mismatches.

Tags: MyBatis java DynamicProxy MapperInterface SQLExecution

Posted on Tue, 09 Jun 2026 17:27:05 +0000 by system