Build a Generic Spring Boot BaseController with MyBatis‑Plus for CRUD Operations
This tutorial shows how to create a reusable BaseController in a Spring Boot application using MyBatis‑Plus, providing generic CRUD, list, pagination, and count endpoints for any entity while demonstrating utility methods, pagination configuration, and concrete controller extensions.
The article introduces MyBatisPlusPro and demonstrates how to build a generic BaseController that supplies common CRUD, list, pagination, and count operations for any entity in a Spring Boot project.
Step 1 – Add MyBatis‑Plus dependency
<code><dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
</code>Step 2 – Create ApprenticeUtil with helper methods for converting between camel‑case and snake‑case, building a QueryWrapper from an entity, and retrieving a field value via reflection.
<code>public class ApprenticeUtil {
private static Pattern humpPattern = Pattern.compile("[A-Z]");
private static Pattern linePattern = Pattern.compile("_(\\w)");
/** Convert camelCase to snake_case */
public static String humpToLine(String str) { /* implementation */ }
/** Convert snake_case to camelCase */
public static String lineToHump(String str) { /* implementation */ }
/** Build QueryWrapper from entity fields */
public static <E> QueryWrapper<E> getQueryWrapper(E entity) { /* implementation */ }
/** Reflectively get a field value */
public static <E> Object getValueForClass(E entity, String value) { /* implementation */ }
}
</code>Step 3 – Implement the generic BaseController that uses the utility class and Spring MVC annotations to expose RESTful endpoints for insert, delete, update, getById, save, list, page, and count.
<code>public class BaseController<S extends IService<E>, E> {
@Autowired
protected S baseService;
@PostMapping("/insert")
public ResponseUtils insert(@RequestBody E entity) { /* ... */ }
@PostMapping("/deleteById")
public ResponseUtils delete(@RequestBody List<Integer> ids) { /* ... */ }
@PostMapping("/updateById")
public ResponseUtils updateById(@RequestBody E entity) { /* ... */ }
@GetMapping("/getById")
public ResponseUtils getById(@RequestParam Integer id) { /* ... */ }
@PostMapping("/save")
public ResponseUtils save(@RequestBody E entity) { /* ... */ }
@PostMapping("/list")
public ResponseUtils list(@RequestBody E entity) { /* ... */ }
@PostMapping("/page")
public ResponseUtils page(@RequestBody PageParamDto<E> pageParamDto) { /* ... */ }
@PostMapping("/count")
public ResponseUtils count(@RequestBody E entity) { /* ... */ }
}
</code>Step 4 – Configure MyBatis‑Plus pagination support
<code>@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
</code>Step 5 – Extend BaseController in concrete controllers (e.g., DynamicController and BlogController ) to obtain the default CRUD functionality without writing additional code.
<code>@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> {}
</code>With these steps, developers can quickly scaffold RESTful APIs for any entity, leveraging MyBatis‑Plus for query construction and pagination while keeping controller code minimal.
Architect's Tech Stack
Java backend, microservices, distributed systems, containerized programming, and more.
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.