Interface Proxy Implementation
Proxy Development Approach
MyBatis enables DAO layer creation through interface proxies. The framework dynamical generates proxy objects implementing mapper interfaces, eliminating manual DAO implementations.
Development Requirements:
- XML mapper namespace must match the interface's fully qualified name
- Method names must correspond to statement IDs in XML
- Parameter types must align with SQL parameter definitions
- Return types must match result type declarations
Mechanism:
- Developer defines interface methods
- MyBatis generates proxy implementation at runtime
- Proxy handles database operations via SqlSession
Testing Proxy Implementation
public Student retrieveEntity(Integer identifier) {
try (InputStream cfgStream = Resources.getResourceAsStream("Configuration.xml");
SqlSession dbSession = new SqlSessionFactoryBuilder().build(cfgStream).openSession(true)) {
StudentRepository repo = dbSession.getMapper(StudentRepository.class);
return repo.findById(identifier);
} catch (IOException ex) {
handleException(ex);
return null;
}
}
Source Analysis
- Proxies are instances of
org.apache.ibatis.binding.MapperProxy - Method execution routes through
MapperMethod.execute() - Command patterns determine CRUD operation routing
Dynamic SQL Constructs
Conditional Logic with <if>
Conditionally include SQL segments based on runtime parameters:
<select id="queryEntities" resultType="Student">
SELECT * FROM students
<where>
<if test="id != 0">AND id = #{id}</if>
<if test="name != null">AND name = #{name}</if>
</where>
</select>
Collection Processing with <foreach>
Iterate over collections for batch operations:
<select id="batchFetch" resultType="Student">
SELECT * FROM students
<where>
<foreach collection="idCollection"
open="id IN (" close=")"
item="itemId" separator=",">
#{itemId}
</foreach>
</where>
</select>
SQL Fragmetn Reuse
Extract reusable SQL components:
<sql id="baseSelect">SELECT * FROM students</sql>
<select id="findById" resultType="Student">
<include refid="baseSelect"/> WHERE id = #{id}
</select>
Key Tags:
<where>: Dynamic WHERE clause handling<if>: Conditional inclusion<foreach>: Collection iteration<sql>/<include>: SQL snippet reuse
Pagination Integration
PageHelper Configuration
- Add dependencies: pagehelper and jsqlparser
- Configure plugin in MyBatis settings:
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<property name="helperDialect" value="mysql"/>
</plugin>
</plugins>
Usage Pattern
PageHelper.startPage(2, 10); // Page 2, 10 items/page
List<User> results = userRepository.findAll();
PageInfo<User> paginationData = new PageInfo<>(results);
Pagination Metrics:
- Total records:
paginationData.getTotal() - Total pages:
paginationData.getPages() - Current page:
paginationData.getPageNum() - Page size:
paginationData.getPageSize()
Multi-Table Relationships
Association Types
- One-to-One: Primary key ↔ Foreign key reference
- One-to-Many: Foreign key in child table
- Many-to-Many: Join table with dual foreign keys
One-to-One Mapping
<resultMap id="passportMap" type="Passport">
<id column="pass_id" property="id"/>
<result column="number" property="serial"/>
<association property="holder" javaType="Person">
<id column="person_id" property="id"/>
<result column="full_name" property="name"/>
</association>
</resultMap>
One-to-Many Mapping
<resultMap id="departmentMap" type="Department">
<id column="dept_id" property="id"/>
<result column="dept_name" property="name"/>
<collection property="staff" ofType="Employee">
<id column="emp_id" property="id"/>
<result column="emp_name" property="name"/>
</collection>
</resultMap>
Many-to-Many Mapping
<resultMap id="studentMap" type="Student">
<id column="stu_id" property="id"/>
<collection property="enrollments" ofType="Course">
<id column="course_id" property="id"/>
<result column="course_title" property="title"/>
</collection>
</resultMap>
Mapping Elements:
<association>: Single-object relationships<collection>: Multi-object relationshipsjavaType/ofType: Target entity types