Project Setup with MyBatis-Plus and Gradle
Start with a standard Spring Boot 2.3.x project using Gradle. Below is a minimal build.gradle configuration:
plugins {
id 'org.springframework.boot' version '2.3.12.RELEASE'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = JavaVersion.VERSION_1_8
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'mysql:mysql-connector-java:8.0.33'
implementation 'com.baomidou:mybatis-plus-boot-starter:3.5.7'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
tasks.named('test') {
useJUnitPlatform()
}
Configure data base and MyBatis-Plus in application.yml:
server:
port: 8090
spring:
datasource:
url: jdbc:mysql://localhost:3306/test_demo?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
username: root
password: 123456
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# Explicitly declare mapper XML locations if non-default
mapper-locations: classpath:/mappers/**/*.xml
Define a mapper interface:
package com.example.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.entity.Item;
public interface ItemMapper extends BaseMapper<Item> {
Item fetchById(Long itemId);
}
Corresponding XML file at src/main/resources/mappers/ItemMapper.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.ItemMapper">
<select id="fetchById" resultType="com.example.entity.Item">
SELECT * FROM t_item WHERE id = #{itemId}
</select>
</mapper>
Enable scanning via configuration class:
@Configuration
@MapperScan("com.example.mapper")
@EnableTransactionManagement
public class PersistenceConfig {}
Common XML Scanning Pitfalls and Fixes
1. Incorrect Resource Directory Name
If you rename src/main/resources/mappers to src/main/resources/xmls, the default classpath*:/mapper/**/*xml pattern no longer matches. To resolve this, explicitly configure mapper-locations in application.yml:
mybatis-plus:
mapper-locations: classpath:/xmls/**/*.xml
2. Storing XML Files Under src/main/java
Placing XML files in side Java source directories (e.g., src/main/java/com/example/mapper/ItemMapper.xml) causes them to be excluded from the build output by default — Gradle does not copy non-Java resources from src/main/java unless instructed.
To include these files, extend the resource processing step in build.gradle:
processResources {
from('src/main/java') {
include '**/*.xml'
include '**/*.properties'
}
}
Alternatively, configure sourceSets more precisely:
sourceSets.main.resources {
srcDirs = ['src/main/resources', 'src/main/java']
excludes = ['**/*.java']
}
After applying either change, rebuild the project. Verify that generated JAR/WAR contains XML files under com/example/mapper/.
3. Verifying Classpath Resolution
At runtime, MyBatis-Plus uses ResourcePatternResolver to locate XML files. The default pattern is classpath*:/mapper/**/*xml. You can confirm resolution behavior by enabling debug logging:
logging:
level:
org.springframework.core.io.support.PathMatchingResourcePatternResolver: DEBUG
This reveals which paths are scanned and which resources are matched.
Best Pratcices
- Prefer placing XML mappers under
src/main/resourceswith conventional naming (/mappers/) to avoid custom configuration. - Avoid mixing XML and Java sources in the same package unless necessary — it complicates builds and IDE indexing.
- Always validate that XML files appear in the final artifact’s classpath before troubleshooting binding errors.
- Use
@Selectannotations for simple queries to bypass XML entirely when appropriate.