SQL Execution Flow Recap
Standard MyBatis execution involves explicit DAO implementation classes handling SQL execution. The typical flow requires:
- Defining a DAO interface
- Implementing the interface with explicit SQL execution logic
- 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:
- Configuration retrieves the
MapperProxyFactoryfor the target interface - Factory creates a
MapperProxyinstance bound to the currentSqlSession 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.