Master Spring Boot & MyBatis Integration: Full Configuration and CRUD Guide
This article walks through setting up Spring Boot 2.3.11 with MyBatis 3.5.6, covering Maven dependencies, pagination and MyBatis configurations, mapper scanning, CRUD mapper definitions, dynamic SQL providers, and comprehensive unit tests, all illustrated with code snippets and diagrams.
Environment: Spring Boot 2.3.11 + MyBatis 3.5.6
Dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>Application Configuration
pagehelper:
helperDialect: mysql
reasonable: true
pageSizeZero: true
offsetAsPageNum: true
rowBoundsWithCount: true
---
mybatis:
type-aliases-package: com.pack.domain
configuration:
lazy-loading-enabled: false
aggressive-lazy-loading: false
logImpl: org.apache.ibatis.logging.stdout.StdOutImpl
mapUnderscoreToCamelCase: trueRefer to the official documentation for detailed explanations of the above settings.
Pagination configuration diagram:
MyBatis configuration diagram:
Adding Mapper Scan in the Startup Class
@SpringBootApplication
@MapperScan({"com.pack.mapper"})
public class SpringBootMyBatisApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootMyBatisApplication.class, args);
}
}After adding @MapperScan, individual mapper interfaces no longer need the @Mapper annotation.
Core processing class:
MapperScannerRegistrar.java public class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {
// implementation details omitted
}The ImportBeanDefinitionRegistrar interface is used to dynamically register beans, similar to how EnableFeignClients registers @FeignClient -annotated classes.
Mapper Interface Definition
public interface UsersMapper {
@Select("SELECT * FROM t_users")
@Results(id = "users", value = {
@Result(property = "name", column = "name", javaType = String.class),
@Result(property = "password", column = "password")
})
List<Users> findAll();
@Select("SELECT * FROM t_users WHERE id = #{id}")
@ResultMap("users")
Users findById(String id);
@Insert("insert into t_users values(#{id}, #{password}, #{username})")
int saveUsers(Users users);
@Update("UPDATE t_users SET username = #{username}, password = #{password} WHERE id = #{id}")
int updateUsers(Users users);
@Delete("DELETE FROM t_users where id = #{id}")
int deleteById(String id);
@SelectProvider(type = UsersProvider.class, method = "selectLikeUsers")
@ResultMap("users")
List<Users> selectLikeUsers(Users users);
@UpdateProvider(type = UsersProvider.class, method = "updateByProvider")
int updateByProvider(@Param("users") Users users);
}Adding an id attribute to @Results allows other methods to reuse the mapping via @ResultMap("users"). The @*Provider annotations enable dynamic SQL generation.
Dynamic SQL Provider
public class UsersProvider {
public String selectLikeUsers(Users users) {
StringBuilder sql = new StringBuilder("SELECT * FROM t_users t where 1=1 ");
if (users.getUsername() != null && users.getUsername().trim().length() > 0) {
sql.append(String.format("and t.username like '%s'", "%" + users.getUsername() + "%"));
}
return sql.toString();
}
public String updateByProvider(@Param("users") Users users) {
SQL sql = new SQL();
sql.UPDATE("t_users")
.SET("username = #{users.username}", "password = #{users.password}")
.WHERE("id = #{users.id}");
return sql.toString();
}
}Unit Tests
@RunWith(SpringRunner.class)
@SpringBootTest
public class UsersMapperTest {
@Resource
private UsersMapper usersMapper;
@Test
public void testFindAll() {
Page<Users> page = PageHelper.startPage(1, 2);
usersMapper.findAll();
System.out.println(page.getResult());
System.out.println(page.getTotal() + "
" + page.getPages());
}
@Test
public void testFindById() {
System.out.println(usersMapper.findById("1"));
}
@Test
public void testSaveUsers() {
Users users = new Users();
users.setId("4");
users.setPassword("123456");
users.setUsername("zhangsan");
System.out.println(usersMapper.saveUsers(users));
}
@Test
public void testUpdateUser() {
Users users = new Users();
users.setId("3");
users.setPassword("111111");
users.setUsername("zhangsan");
System.out.println(usersMapper.updateUsers(users));
}
@Test
public void testDeleteById() {
System.out.println(usersMapper.deleteById("3"));
}
@Test
public void testSelectLikeUsers() {
Users users = new Users();
users.setUsername("gu");
System.out.println(usersMapper.selectLikeUsers(users));
}
@Test
public void testUpdateByProvider() {
Users users = new Users();
users.setId("2");
users.setPassword("111111");
users.setUsername("guest");
System.out.println(usersMapper.updateByProvider(users));
}
}All steps are complete.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
