How to Build a Reusable CRUD BaseController with MyBatis‑Plus in Spring Boot

This tutorial walks through creating a generic BaseController that provides CRUD, list, pagination, and count operations for any entity by adding MyBatis‑Plus, writing a utility class for query building, configuring a pagination interceptor, and extending the base class in concrete controllers, all illustrated with complete Java code snippets.

Java Web Project
Java Web Project
Java Web Project
How to Build a Reusable CRUD BaseController with MyBatis‑Plus in Spring Boot

Step 1 – Add MyBatis‑Plus Dependency

Include the Maven artifact com.baomidou:mybatis-plus-boot-starter:3.4.2 in pom.xml to bring MyBatis‑Plus into the Spring Boot project.

Step 2 – Utility Class ApprenticeUtil

This class supplies three reusable helpers: humpToLine(String str) converts camel‑case to snake_case by matching uppercase letters with a Pattern and inserting an underscore before each, then lower‑casing the result. lineToHump(String str) performs the reverse conversion by matching _(\w) and capitalising the captured character. getQueryWrapper(E entity) uses reflection to iterate over all non‑final fields of entity, builds a QueryWrapper<E>, and adds an eq condition for each non‑null field, converting the field name to snake_case via humpToLine.

Additional overloaded methods getValueForClass demonstrate how to retrieve a specific property value via JavaBeans PropertyDescriptor and Spring's ReflectionUtils, handling NoSuchFieldException and IntrospectionException.

Step 3 – Generic BaseController&lt;S extends IService&lt;E&gt;, E&gt;

The controller is annotated with Spring MVC and Swagger annotations and injects the generic service S baseService. It defines the following endpoints, each delegating to the corresponding IService method and wrapping the result with ResponseUtils.success(...): @PostMapping("/insert")

baseService.save(entity)
@PostMapping("/deleteById")

baseService.removeByIds(ids)
@PostMapping("/updateById")

baseService.updateById(entity)
@GetMapping("/getById")

baseService.getById(id)
@PostMapping("/save")

baseService.saveOrUpdate(entity)
@PostMapping("/list")

– builds a QueryWrapper via ApprenticeUtil.getQueryWrapper(entity) and returns baseService.list(queryWrapper). @PostMapping("/page") – validates page (minimum 1) and size (maximum 100), constructs a Page<E>, applies optional ascending/descending order fields from PageParamDto, and returns baseService.page(page, queryWrapper). @PostMapping("/count") – uses the same QueryWrapper to call baseService.count(queryWrapper).

Step 4 – Enable Pagination

MyBatis‑Plus does not enable pagination by default. Register a PaginationInnerInterceptor for MySQL in a configuration class:

@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

Step 5 – Extend BaseController in Concrete Controllers

Concrete controllers inherit from BaseController and specify the service interface and entity type. No additional CRUD code is required.

@RestController
@RequestMapping("/apprentice/dynamic")
@Api("Dynamic Management")
public class DynamicController extends BaseController<IDynamicService, Dynamic> {}
@RestController
@RequestMapping("/apprentice/blog")
@Api(tags = "Blog Management")
public class BlogController extends BaseController<IBlogService, Blog> {}

Project Source

Full source code is available at:

https://gitee.com/WangFuGui-Ma/mybatis-plus-pro

JavaSpring BootPaginationMyBatis-PlusREST APICRUDBaseController
Java Web Project
Written by

Java Web Project

Focused on Java backend technologies, trending internet tech, and the latest industry developments. The platform serves over 200,000 Java developers, inviting you to learn and exchange ideas together. Check the menu for Java learning resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.